/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;
},
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
This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 5 years ago.
I have init the array ArtificialInsemination[] on response received but its not showing or loading the records in the table. When I click the button its calls the functions viewRecords and sends the HTTP request successfully, but not loading into the table.
<div id="ArtificialInsemination" class="container">
<button v-on:click="viewRecords">View Record</button>
<table class="table table-striped">
<thead>
<tr>
<th>Cow Id</th>
<th>Bull Name</th>
<th>Semen Origin</th>
<th>Insemination Time</th>
<th>Pd Delivery Date</th>
</tr>
</thead>
<tbody>
<tr v-for ="artificialInseminationRecord in artificialInseminationRecords">
<td>{{ artificialInseminationRecord.cowId }}</td>
<td>{{ artificialInseminationRecord.bullUsedName }}</td>
<td>{{ artificialInseminationRecord.semenOrigin }}</td>
<td>{{ artificialInseminationRecord.inseminationTime }}</td>
<td>{{ artificialInseminationRecord.pdStatusDate }}</td>
</tr>
</tbody>
</table>
</div>
This is the vue
<script src="https://unpkg.com/vue#2.0.3/dist/vue.js"></script>
<script src="https://unpkg.com/axios#0.12.0/dist/axios.min.js"></script>
<script src="https://unpkg.com/lodash#4.13.1/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.5/jspdf.debug.js"></script>
<script>
//class initialization
var ArtificialInsemination = new Vue({
el:'#ArtificialInsemination',
data: {
url:'http://localhost/dairyfarm/index.php',
artificialInseminationRecords: []
},
//invoke methods
methods: {
viewRecords:function () {
var data = new FormData()
data.append('function','viewRecords')
axios.post(this.url,data)
.then( function (response ) {
this.artificialInseminationRecords = response.data.data
}).catch(function (error) {
})
},
created: function(){
this.viewRecords()
}
}
})
</script>
You have a scoping issue, this inside a callback refers to the execution context of the callback not the Vue instance. You need to either assign this to something outside the callback:
// assign this to self
var self = this;
axios.post(this.url,data)
.then( function (response ) {
self.artificialInseminationRecords = response.data.data
}).catch(function (error) {
})
Or use an arrow function which do not create their own execution context:
axios.post(this.url,data)
.then( response => {
this.artificialInseminationRecords = response.data.data
}).catch(function (error) {
})
You decided to use created event, but you defined it as a method. :)
Look at this sample:
Async Data Mutation inside of Created Event
We only needed to add bind like this
viewRecords:function () {
var data = new FormData()
data.append('function','viewRecords')
axios.post(this.url,data)
.then( function (response ) {
this.artificialInseminationRecords = response.data.data
}.bind(this)).catch(function (error) {
})
}
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}}
I am new to angularjs. I want to display the data in the following json file using ng-repeat.
http://www.cricbuzz.com/api/match/current
But I'm confused as there is a number in the data as key to each object. Can someone help me?
THis is a basic way to do it
Partial
<div ng-controller="Ctrl" >
<table>
<thead>
<tr>
<th>Id</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in rows">
<td>#{{ row.id}}</td>
<td>{{ row.series.name | uppercase }}</td>
</tr>
</tbody>
</table>
</div>
Controller
angular.module('app').controller('Ctrl', ['$scope', 'Resource', function ($scope, Resource) {
var pageChanged = function () {
$scope.myPromise = Resource.get({}, function (response) {
$scope.rows = response;
});
};
pageChanged();
}])
.factory('Resource', ['$resource', function($resource) {
return $resource('http://www.cricbuzz.com/api/match/current', {
}, {
'get': {
method: 'GET',
headers: {"Content-Type": "application/json"}
}
});
}]);