ng-repeat issue with JSON Object - javascript

So I'm trying to print the keys and values of a simple JSON object inside an HTML table with ng-repeat but not able to print it on the html page. The JSON object has been received from the backend and am trying to populate that in the frontend. I understand that I am doing a silly mistake somewhere but can't understand where.
JSON Object
json_data ={
user1 : "matt",
user2 : "kim",
user3 : "Tim"
}
$scope.rows = json_data;
HTML code..
<table ng-if="displayTable">
<caption>Results</caption>
<tr>
<th>Username</th>
<th>Name</th>
</tr>
<tr ng-repeat="(key, value) in rows">
<td> {{key}} </td> <td> {{ value }} </td>
</tr>
</tr>
</table>
Can't understand what silly mistake I am doing here.

Try {{rows.key}} and {{rows.value}}. Although I don't thing this is the answer. Give it a try..
Alternative ly you can try to see if it works with just one , either key or value...

First at all, the (key, value) is more well represented by (index, value).
A correct version of this piece of code will output this:
0 {"user1":"matt","user2":"kim","user3":"Tim"}
which 0 is the first index of an array and the json is the entire value.
So, i guess you are using a bad approach.
Try to modify your array to something like that:
$scope.rows = [
{key: 'user1', user: 'matt'},
{key: 'user1', user: 'kim'},
{key: 'user1', user: 'Tim'},
];
And modify your HTML to:
<table ng-if="displayTable">
<caption>Results</caption>
<tr>
<th>Username</th>
<th>Name</th>
</tr>
<tr ng-repeat="row in rows">
<td> {{row.key}} </td> <td> {{ row.user }} </td>
</tr>
</tr>
</table>

Related

How to bind an object to HTML table in Vue.js, where its properties are dynamically created?

I am using vue.js library for front-end development.
I came a cross a scenario where my JavaScript method returns a list, which has objects, object's number of properties can change each time after method execution.
example my list can contain these type of objects in 2 different executions.
var obj = {
Name : "John",
2020-Jan: 1,
2020-Jul: 2
}var obj = {
Name: "John",
2020-Jan: 1,
2020-Jul: 2,
2021-Jan: 3,
2021-Jul: 4
}
Since Property name is dynamically changes is there any way to bind to HTML ?
<div >
<table>
<thead>
<tr>
<th v-for ="row in Result.Headers">
{{row}}
</th>
</tr>
</thead>
<tbody>
<tr v-for="item in Result.Data ">
<td>
{{item.2020-Jan}} // Because don't know the number of properties until run time
</td> // No of <td/>'s can change on no of properties.
<td> // exactly don't know how many <td>'s needed there.
{{item.2020-Jul}}
</td> <td>
{{item.2021-Jan}}
</td>
</tr>
</tbody>
</table>
</div>
Is there way to bind these type of object to fronted in vue.js ?
You need to loop over the item's keys again. This will show all the values in the object
<tbody>
<tr v-for="item in Result.Data ">
<td v-for="(value, key, index) in item">
{{value}}
</td>
</tr>
</tbody>
If you want to filter some of them, for instance check that the keys are valid dates you need to add a v-if and use Date.parse to check for this.
<tbody>
<tr v-for="item in Result.Data ">
<td v-for="(value, key, index) in item" v-if="Date.parse(key) !== NaN">
{{value}}
</td>
</tr>
</tbody>
if u wana show all attr-> u can use this:
<ul v-for="item in Result ">
<li v-for="(value,key,index) in item">{{value}}</li>
</ul>
if u wana show all days u can use v-if and compute to complete youself fillter
<div id="app">
<ul v-for="item in Result" >
<li v-for="(value,key,index) in item" v-if="canShow(key)"> index:{{index}}------ key: {{key}} ------ value:{{value}} </li>
</ul>
</div>
<script>
var vue=new Vue({
el:'#app',
data:{
Result:[{
name: 'SkyManss',
2020-Jan: 1,
2020-Jul: 2
},{
name: 'SkyManss2',
2020-Jan: 1,
2020-Jul: 2,
2021-Jan: 3,
2021-Jul: 4
}]
},
computed:{
canShow(){
return function(skey){
return skey.indexOf('-') > -1;
}
}
}
});
</script>
after some research and some of your suggestions I came up with an answer.
<div>
<table>
<thead>
<tr>
<th v-for ="row in Result.Headers">
{{row}}
</th>
</tr>
</thead>
<tbody>
<tr v-for="item in Result.Data ">
<td v-for="row in Result.Headers">
{{item[row]}}
</td>
</tr>
</tbody>
</table>
</div>
Javascript code
this.Result.Headers = Object.keys(result.data[0]);
this.Result.Data = result.data;
But this code only worked for the first time. second time data didn't get updated. So I updated JavaScript code to following code.
Vue.set(self.Result, 'Headers', []);
Vue.set(self.Result, 'Result', []);
this.Result.Headers = Object.keys(result.data[0]);
this.Result.Data = result.data;
Vue does not allow dynamically adding new root-level reactive properties to an already created instance. That I got to know from following post.
vue.js is not updating the DOM after updating the array
Thank You All !!!

Using nested ng-repeat with object arrays angular

Here is what I am trying to do:
<tr ng-repeat = "data in tabularData track by $index" >
<td ng-repeat ="(key,value) in usedAttributes" >{{data[key]}}</td>
</tr>
This DID work when the tabular Data was structured like this:
[3920F0-3434D3-ADF-3SDF:[{CreatedBy: "John Doe", CreatedDate: "10-20-2016"}]
However when I flattened it out, it looks more like this:
[{CreatedBy: "John Doe", CreatedDate: "10-20-2016",PrimaryID:"3920F0-3434D3-ADF-3SDF"}]
This does not work. I feel like I'm missing something very obvious.
usedAttributes is just a simple object array containing attributes (column data). The idea is that the user can choose the attributes they want to get so the data table is very dynamic. For this example, the usedAttributes may look like this:
["CreatedBy": [{Checked:false}],"CreatedDate":[{Checked:true}]]
Thus the user wants to see these two attributes although more exists.
You can do this,
<div ng-controller="listController">
<table class="table table-striped">
<thead>
<tr>
<th ng-repeat="(key, value) in tabularData[0]">{{key | uppercase }}
</th>
</tr>
<tbody>
<tr ng-repeat="val in tabularData">
<td ng-repeat="cell in val">
<input type="text" ng-model="cell">
</td>
</tr>
</tbody>
</table>
</div>
DEMO

How convert angular object to JS object

I have a table, One column by expressing object with an angular ng-repeat in angular
<table class="table table-bordered table-hover table-condensed " ng-show="vm.CandidatesList">
<thead>
<tr>
<th sortable-header col="FirstName" style="text-align:center">{{::vm.resources.FirstName}}</th>
<th sortable-header col="LastName" style="text-align:center">{{::vm.resources.LastName}}</th>
<th sortable-header col="CandidateTopic" style="text-align:center">{{::vm.resources.CandidateTopic}}</th>
</tr>
</thead>
<tr ng-repeat="c in vm.CandidatesList "
row-id="{{ c.ID }}"
ng-dblclick="vm.goEdit(c.ID)">
<td ng-model="c.FirstName" style="text-align:center">{{c.FirstName}}</td>
<td ng-model="c.LastName" style="text-align:center">{{c.LastName}}</td>
<td style="text-align:center" name="TopicToCandidate" id="TopicToCandidate+{{c.ID}}"><a ng-repeat="t in vm.getTopicToCandidate(c.ID)">{{t.Name}}, </a></td>
</tr>
now I want to recive the value of the TopicToCandidateto js with
var topic= document.getElementById("TopicToCandidate+" + item.ID).innerText
but topic is null because js can not convert the angular object or HTML object to js object.
I'm not sure you understand what angularjs does in the background. Don't extract the information from the DOM if you already have it in your controller.
So in other words just use it like this:
app.controller('candidateController', function($scope) {
$scope.CandidatesList = [
{ID:1 , FirstName:"Dan1", LastName:"Doe1"},
{ID:2 , FirstName:"Dan2", LastName:"Doe2"},
{ID:3 , FirstName:"Dan3", LastName:"Doe3"}
];
//get topic of first candidate for example
var topic = $scope.getTopicToCandidate($scope.CandidatesList[0]);
}
You might want to check out 2 way binding in the angular docs.

How to repeat "key" in ngRepeat one time only (AngularJS)

The problem is leaving in the JSON Array response from the Backend/DB. I'm getting the response of the database in the correct json format:
[
0: {
"Grade": 100,
"AB001": 1,
"AB002": 0,
"AB003": 9,
"AB004": 5
},
1: {
"Grade": 98,
"AB001": 3,
"AB002": 0,
"AB003": 0,
"AB004": 0
}
...
] (10 objects as result)
Thus displayed in the Firebug console, when you click the Response of the GET Request. To retrieve the keys who are represented in double quotes I've used the ngRepeat directive in my view like following:
<thead>
<tr ng-repeat="d in data">
<th ng-repeat="(key, value) in d">
{{key}}
</th>
</tr>
</thead>
...
Only the problem is, that the key gets repeated 10 times. But I want to repeat the keys one time that means for example the key Grade is only one time in a th-tag and so on..
How can I implement this? I've tried it with angular's forEach() but it wasn't a solution.
If you have the exact same keys in each object in the array, you could achieve this with:
<thead>
<tr>
<th ng-repeat="(key, value) in data[0]">
{{key}}
</th>
</tr>
</thead>
In your snippet you are doing a double loop, listing each key, for each element in the array.
You could use the unique filter from AngularUI (source code available here: AngularUI unique filter) and use it directly in the ng-options (or ng-repeat).
Try This:
<thead>
<tr ng-repeat="d in data">
<th ng-repeat="(key, value) in d | unique:'key'">
{{key}}
</th>
</tr>
</thead>
this answer may be help you
<thead>
<tr ng-repeat="d in data">
<th ng-if="$parent.$index == 0" ng-repeat="(key, value) in d">
{{key}}
</th>
</tr>

Loop through array in array with Angular

Working on a TODO-app to learn Angular. I have this hardcoded array as a "database" and i want to display the tasks in the view.
var taskLists = [
{name: 'Todays todo', id: '1', tasks:['Make coffe', 'another task']},
{name: 'Tomorrow i will do this', id: '2', tasks:['Code well', 'go to bed']}
];
So how do i iterate through an array inside an array in an angular-view?
I tried to have two ng-repeats but cant get it to work right. I want to display the tasks one by one as <td>, not just the whole tasks array as one <td> as it does right now ['Make coffe', 'another task']
This is what the view looks like.
<h2 ng-repeat="object in list">{{object.name}}</h2>
<table>
<thead>
<tr>Tasks</tr>
</thead>
<tr>
<td ng-repeat="task in list">{{task.tasks}}</td>
</tr>
</table>
You have a problem in your logic.
Fist your HTML tag from child must be inside the parent.
<div class="parent" ng-repeat="object in list">
<h2>{{object.name}}</h2>
<table>
<thead>
<tr>Tasks</tr>
</thead>
<tr ng-repeat="task in object.tasks">
<td>{{item}}</td>
</tr>
</table>
</div>
Try this and check if it works.

Categories