How to fetch data from console output to table using angular2 - html

I have a table in HTML, i need to fetch data from consoled output to the table. Please help.
HTML Code:
<table class="table">
<tr>
<th>Completed On</th>
<th>ID</th>
<th>ParticipantId</th>
</tr>
<tr *ngFor="let data of result">
<td>{{ data.completedOn }}</td>
<td>{{ data.id }}</td>
<td>{{ data.participantId }}</td>
</tr>
</table>
TS Code:
public result:any = [];
this.service
.getParticipent(comparedCampaign.id,token)
.subscribe(
participent => {
this.loading = false;
// this.result = data;
console.log( this.result);
var survey = this.surveyResults;
if(participent.length > 0) {
var data =[];
participent.map(function(item) {
var list = survey.filter(function(result) {
if(result.participantId) {
return result.participantId == item.id
}
})
data.push(list);
this.result = data;
console.log( this.result);
})
console.log(data);
} else {
alert('No Participent found!');
}
}, error => {
console.log(error)
})
}
}
From this i need to fetch CompletedOn, id and participantId to the table
JSON Consoled output:
[[{"satisfaction":"[object Object]","completedOn":"2017-08-22T08:52:55.788Z","id":3,"participantId":217},{"satisfaction":{"price":"less","recomondation":"1","winback":"reason6"},"completedOn":"2017-08-22T09:12:40.800Z","id":4,"participantId":217},{"satisfaction":{"price":"less","recomondation":"1","winback":"reason6"},"completedOn":"2017-08-22T11:36:04.861Z","id":5,"participantId":217},{"satisfaction":{"price":"less","recomondation":"1","winback":"reason6"},"completedOn":"2017-08-22T11:59:24.334Z","id":6,"participantId":217},{"satisfaction":{"price":"medium","customer":"yes","recomondation":"2","sales":["phone","Shop","webshop"],"webVist":"5","shopVist":"5","phoneVist":"5","prodandService":["{product_list}"],"importance":["Service"],"frequence":"quarter","satisfaction":"3"},"completedOn":"2017-08-22T12:20:54.280Z","id":7,"participantId":217},{"satisfaction":{"price":"medium","customer":"no","recomondation":"1","winback":"reason1","winback_quality":"reason2"},"completedOn":"2017-08-22T12:22:43.153Z","id":8,"participantId":217},{"satisfaction":{"prodandService":[{"index":"Orbiz"},{"index":"qwerq"},{"index":"asfd"},{"index":"test"},{"index":"test123"},{"index":"TestWD"},{"index":"IOS app"},{"index":"Lipstick"},{"index":"Foundation"},{"index":"lipstick"},{"index":"Website"},{"index":"App IOS"},{"index":"Shampoo Vanilla"},{"index":"Shampoo Strawberry"},{"index":"car"},"Lipstick"],"price":"medium","customer":"yes","recomondation":"4","sales":["phone"],"phoneVist":"3","importance":["Quality"],"frequence":"quarter","satisfaction":"3"},"completedOn":"2017-08-28T09:39:54.676Z","id":10,"participantId":217},{"satisfaction":{"prodandService":[{"index":"Orbiz"},{"index":"qwerq"},{"index":"asfd"},{"index":"test"},{"index":"test123"},{"index":"TestWD"},{"index":"IOS app"},{"index":"Lipstick"},{"index":"Foundation"},{"index":"lipstick"},{"index":"Website"},{"index":"App IOS"},{"index":"Shampoo Vanilla"},{"index":"Shampoo Strawberry"},{"index":"car"},"Foundation","IOS app","test123","test"],"price":"medium","customer":"yes","recomondation":"5","sales":["visits"],"salesVist":"3","importance":["Quality"],"frequence":"year","satisfaction":"5","knowledge":["IOS app","Foundation","Website"],"development":"littleLess","suppliers":"yes","competators":"60","competators_reasons":"Quality","Need":["{product_list}"],"service":"5","collaboration":"4","continuedCollaboration":"3","improvements":["Service","Price"],"winback":"reason3"},"completedOn":"2017-08-28T14:45:13.991Z","id":11,"participantId":217},{"satisfaction":{"prodandService":[{"index":"Orbiz"},{"index":"qwerq"},{"index":"asfd"},{"index":"test"},{"index":"test123"},{"index":"TestWD"},{"index":"IOS app"},{"index":"Lipstick"},{"index":"Foundation"},{"index":"lipstick"},{"index":"Website"},{"index":"App IOS"},{"index":"Shampoo Vanilla"},{"index":"Shampoo Strawberry"},{"index":"car"},"TestWD","Lipstick"],"price":"less","recomondation":"4","sales":["phone"],"phoneVist":"3","importance":["Quality","Assortment"],"frequence":"quarter","satisfaction":"4","knowledge":["IOS app"],"Need":["TestWD","Lipstick"],"development":"same","suppliers":"yes","competators":"60","competators_reasons":"Assortment","service":"4","collaboration":"4","continuedCollaboration":"3","improvements":["Assortment"],"winback":"reason4"},"completedOn":"2017-09-01T14:23:04.533Z","id":13,"participantId":217}]]
with error:
"EXCEPTION: Cannot set property 'result' of undefined"
Please Help.
Thanks in advance

You need to access the 0th index of the array and then assign to the result,
this.service.getParticipent(comparedCampaign.id,token).subscribe(
participent => {
this.result = participent[0];
}
then you can iterate over and display as you mentioned above,
<tr *ngFor="let data of result">
<td>{{ data.completedOn }}</td>
<td>{{ data.id }}</td>
<td>{{ data.participantId }}</td>
</tr>

i guess you are showing array in wrong format so try this
this.service.getParticipent(comparedCampaign.id,token).subscribe(
participent => {
this.result = participent;
}
and use your array like this
<tr *ngFor="let data of result">
<td>{{ data?.completedOn }}</td>
<td>{{ data?.id }}</td>
<td>{{ data?.participantId }}</td>
</tr>
also please try to print whole array in HTML too, for better understanding like this
{{result | json}}

Related

Why I cannot see json data in table?

I am trying to display json data in tree hierachy table with vue.js. Unfortunally I cannot see any data inside of the table. The path is correct, I have checked this by URL adress, the format as well. My goal is to create tree hierarchy table, with action button for removing layers. I would like to mention thath I am new in Vue.js framework, so this is not maybe the best option how to work with fetched data from json file.
HTML:
<table>
<thead>
<tr>
<th>Name</th>
<th>Parent</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr v-for="item in items" :key="item.id">
<td>{{ item.name }}</td>
<td>{{ item.parent }}</td>
<td>
<button #click="toggleChildren(item)">Toggle Children</button>
</td>
<template v-if="item.childrenVisible">
<tr v-for="child in item.children" :key="child.id">
<td>{{ child.name }}</td>
<td>{{ child.parent }}</td>
<td>
<button #click="toggleChildren(child)">Toggle Children</button>
</td>
</tr>
</template>
</tr>
</tbody>
</table>
</div>
Vue.js code
<script>
fetch('data/vue-data.json')
.then(response => response.json())
.then(data => {
new Vue({
el: '#app',
data: {
items: data.items
},
methods: {
toggleChildren(item) {
item.childrenVisible = !item.childrenVisible;
},
}
});
})
</script>
you create your app in advance. also where is your #app container?
<div id="app">
<!-- your table data -->
</div>
and for the js
new Vue({
el: '#app',
// data should return an object, not be an object
data() {
return {
items: [] // default value, could also be null
}
},
// called on initialization, read about lifecycle hooks
mounted() {
fetch('data/vue-data.json').then(response => { this.items = response.json() })
},
methods: {
toggleChildren(item) {
item.childrenVisible = !item.childrenVisible;
},
}
});

How can I make my Delete Entry Button Functional

Pardon my novice as I am new to coding. I have been trying to get my delete button to work both on my webpage and mysql, but my delete button just takes me to a url /delete page. I do not get any errors, but my confirm delete button does not remove the entry, but takes me to another blank page. If any advice could be spared it would be greatly appreciated. Here is some code, if more is need let me know. Thanks again.
<template>
<div class="between:flex bottom:margin-3">
<div class="center: flex-items">
<span class="right:margin-1">Show</span>
<select v-model="currentEntries" class="select" #change="paginateEntry">
<option v-for="se in showEntries" :key="se" :value="se">
{{ se }}
</option>
</select>
<span class="left:margin-1">Entries</span>
<div class="end:flex"></div>
</div>
</div>
<div id="tableHolderDiv">
<table class="table table-striped">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">Location</th>
<th scope="col">End User</th>
<th scope="col">Order Number</th>
<th scope="col">Date</th>
<th scope="col">Application</th>
<th scope="col">Service Tech</th>
<th scope="col">Department</th>
<th scope="col">Hours</th>
<th scope="col">Travel Hours</th>
<th scope="col">Contact Name</th>
<th scope="col">Reason</th>
</tr>
</thead>
<tbody>
<tr
v-for="row in serviceEntries"
:key="row.id"
#click="alertID(row.id)"
>
<th scope="row">{{ row.id }}</th>
<td>{{ row.location }}</td>
<td>{{ row.end_user }}</td>
<td>{{ row.order_number }}</td>
<td>{{ row.date }}</td>
<td>{{ row.application }}</td>
<td>{{ row.service_tech }}</td>
<td>{{ row.department }}</td>
<td>{{ row.hours }}</td>
<td>{{ row.travel_hours }}</td>
<td>{{ row.contact_name }}</td>
<td>{{ row.reason }}</td>
<a
href="/delete/{{this.id}}"
type="button"
class="btn btn-light btn-small"
onclick="event.stopPropagation(); return confirm('Are you sure you want to delete this entry?');"
><i class="bi bi-trash"></i> Delete</a
>
</tr>
</tbody>
</table>
</div>
</template>
<script>
import axios from "axios";
export default {
name: "ServiceTable",
computed: {
serviceEntries() {
return this.$store.state.serviceEntries;
},
},
methods: {
alertID(id) {
this.$router.push({
path: `/modify/${id}`,
});
},
},
async onDelete() {
if (!confirm("Are you sure you want to delete this entry?")) {
return;
}
await axios.delete(`/api/service/delete/${this.id}`);
},
alertID(id) {
this.$router.push({
path: `/modify/${id}`,
});
},
};
</script>
This is in my index.js
async deleteServiceEntry() {
return new Promise((resolve, reject) => {
axios({
method: "delete",
url:
prefix +
"/api/service/delete/",
headers: { "Content-Type": "application/json" }
})
.then(function(response) {
//handle success
console.log(response);
resolve(true);
})
.catch(function(response) {
//handle error
console.log(response);
reject(false);
});
});
},
This is in my app.js
app.delete("/api/service/:id", (req, res) => {
// console.log("DELETE /api/user/" + req.params.id + " called");
pool.query(
"DELETE FROM `master` WHERE id = ?",
[req.params.id],
function (error, results, fields) {
if (error) res.json(error);
else res.json(results);
}
);
});
app.delete("/api/service/:id", (req, res) => {
pool.query(
"DELETE FROM `master` WHERE id= ? AND location = ? AND end_user = ? AND order_number = ? AND date = ? AND application = ? AND service_tech = ? AND department = ? AND hours = ? And travel_hours = ? AND contact_name = ? AND reason = ?",
[req.params.id, req.params.location, req.params.end_user, req.params.order_number, req.params.date, req.params.application, req.params.service_tech, req.params.department, req.params.hours, req.params.travel_hours, req.params.contact_name, req.params.reason],
function (error, results, fields) {
if (error) res.json(error);
else res.json(results);
}
);
});
It is redirecting to a new page because of the href link in the anchor tag. You should call the method deleteServiceEntry on the click and it should work fine. What you can do is:
<a
href="#"
type="button"
class="btn btn-light btn-small"
#click="deleteServiceEntry($event,row.id)"
><i class="bi bi-trash"></i> Delete</a
>
Then in the method:
async deleteServiceEntry(event,id) {
event.preventDefault();
const verify = confirm("Are you sure you want to delete this entry?");
if (verify) {
return new Promise((resolve, reject) => {
axios({
method: "delete",
url:
prefix +
"/api/service/delete/"+id,
headers: { "Content-Type": "application/json" }
})
.then(function(response) {
//handle success
console.log(response);
resolve(true);
})
.catch(function(response) {
//handle error
console.log(response);
reject(false);
});
});
},
}
Hope this was helpful.

how do i loop through a json object from an api in vuejs?

/Dear All,
I would like to create a table from this API created JSON object, how can I use v-for in Vue js ? design is not important I just cannot implement v-for in this case? the table should not be fancy just a plane html table/
<template>
<div id="app">
<table>
<thead>
<tr>
<th>id</th>
<th>meta</th>
<th>title</th>
<th>is private</th>
</tr>
</thead>
</table>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
items:''
}
},
created() {
axios.get(`https://zbeta2.mykuwaitnet.net/backend/en/api/v2/pages/`)
.then(response => {
this.items = response.data
})
}
}
</script>
<style>
</style>
Your HTML table:
<table>
<thead>
<tr>
<th>id</th>
<th>meta</th>
<th>title</th>
<th>is private</th>
</tr>
</thead>
<tbody>
<tr v-for="item in items" :key="item.id">
<td>{{ item.id }}</td>
<td>{{ item.meta.detail_url }}</td>
<td>{{ item.title }}</td>
<td>{{ item.is_private }}</td>
</tr>
</tbody>
</table>
Script:
async created() {
const response = await axios.get(
`https://zbeta2.mykuwaitnet.net/backend/en/api/v2/pages/`
);
this.items = response.data.items;
},

error TS2571: Object is of type 'unknown' when try pipe slice in *ngFor

I trying to use NGB Pagination on my angular app in a table. But when i use pipe slice in my *ngFor, my Angular appear error TS2571: Object is of type 'unknown' when try slice. This is my code:
My HTML code:
<tr *ngFor="let row of documentaryList|slice: (page-1) * pageSize : page * pageSize" class="text-md text-md-center">
<td>{{ row.documentDate }}</td>
<td><a class="text-info" routerLink="details-documentary/{{row._id}}">{{ row.documentName }}</a></td>
<td>{{ row.documentNumber }}</td>
<td>{{ row.documentType }}</td>
<td>{{ row.documentAddress }}</td>
<td>
My .ts code:
export class ListDocumentaryComponent implements OnInit {
title = 'Documentary';
documentaryList: any;
page = 1;
pageSize = 10;
lengthDocumentList = 0;
constructor(private documentaryService: DocumentaryService) {
}
ngOnInit(): void {
this.getDocumentaryList();
}
getDocumentaryList(): any {
this.documentaryService.getDocumentary()
.subscribe((data: any) => {
this.documentaryList = data.data;
this.lengthDocumentList = this.documentaryList.length;
});
}
}
My Object in console:
And my Error:
Thanks for your help!
Change documentaryList: any; to documentaryList: any[] = [];

Looping over JSON array using *ngFor

I currently have the following JSON file:
[
{
"Arsenal": {
"form": {
"away": 4.6064800860172,
"home": 2.2108841763771
},
"stadium": "Stadium 1"
}
},
{
"Man City": {
"form": {
"away": 4.9473459270023,
"home": 5
},
"stadium": "Stadium 2"
}
},
{
"Man Utd": {
"form": {
"away": 5,
"home": 3.2296790061981
},
"stadium": "Stadium 3"
}
}
]
and I want to display this data in a table. I currently have a service that retrieves the JSON file and returns it
public getJSON(): Observable<any> {
return this.http.get('assets/teams.json')
.map(
(response: Response) => {
const data = response.json();
return data;
}
);
}
I then subscribe to it in my component and save it to teams.
teams = [];
loadJSON() {
this.teamService.getJSON().subscribe(
(teams: any[]) => this.teams = teams,
(error) => console.log(error)
);
}
and using the following HTML
<div class="container">
<table class="table">
<thead>
<tr>
<th>Team</th>
<th>Home</th>
<th>Away</th>
<th>Stadium</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let team of teams | keys">
<td>{{ (team.value | keys)[0].key }}</td>
<td>{{ (team.value | keys)[0].value["form"]["home"] }}</td>
<td>{{ (team.value | keys)[0].value["form"]["away"] }}</td>
<td>{{ (team.value | keys)[0].value["stadium"] }}</td>
</tr>
</tbody>
</table>
</div>
gives the table seen below
Surely there must be a better way of doing this? How can I do this in a more straight-forward way, that is a lot more readable? For example, if the key was actually "Arsenal", "Man City" and "Man Utd" instead of 0, 1 and 2 respectively, it would be much more readable. Why does it have those keys instead? I'm used to coding in Python so it doesn't really make much sense to me.
A working stackblitz can be found here.
I propose to have your own Team object and map your JSON on it.
So in your teams.service you have:
public getJSON(): Observable<Team[]> {
return this.http.get('assets/teams.json')
.map(teams => teams.map(team => this.mapTeam(team)))
}
private mapTeam(res: any): Team {
const teamName = Object.keys(res)[0]
return new Team(
teamName,
{away: res[teamName].form.away, home: res[teamName].form.home},
res[teamName].stadium
)
}
Your Team class can be like this:
export class Team {
constructor(public name: string,
public form: { away: number, home: number },
public stadium: string) {
}
}
It's not the subject of your question but in this the Team class it's preferable to have private properties and have getter to access it.
In your component.ts:
Just call your service and assign the value of the subscribe: this.teamService.getJSON().subscribe(value => this.teams = value)
There are antother way to do this part but it's not your question too
And finally your html it's more readable:
<div class="container">
<table class="table">
<thead>
<tr>
<th>Team</th>
<th>Home</th>
<th>Away</th>
<th>Stadium</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let team of teams">
<td>{{ team.name }} </td>
<td>{{ team.form.home }}</td>
<td>{{ team.form.away }}</td>
<td>{{ team.stadium }}</td>
</tr>
</tbody>
</table>
</div>
The stackblitz here: https://stackblitz.com/edit/angular-gwj6nb