My json array is
{
"object": {
"assignments": [
{
"assignmentId": 14706368,
"sectionId": 0,
"assignmentTitle": "file attachment A",
"assignmentStartDate": "01/01/1900",
"assignmentStartTime": "01:00AM",
"assignmentDueDate": "01/01/2100",
"assignmentDueTime": "01:00AM",
"isMarathonChain": "No",
"assignmentTimeLimit": 0,
"assignmentTimeRemaining": "0",
"marathonAssignmentStatus": "MARATHON_NOT_ASSOCIATED",
"showAssignmentAttemptsAndPasswordDetails": false,
"assignmentAttemptsTaken": 0,
"assignmentAttemptsAllowed": "1",
"showPasswordForm": false,
"isStartAssignment": true,
"isResumeAssignment": false,
"isSubmitAssignment": false,
"passwordRequired": false,
"isConvertToGeniusEnabled": false,
"draftNumber": 0,
"studentExceptionExistsForDueDate": false,
"isPastUploadDate": false,
"showMarathonPrerequisiteInfo": false
}
],
"sections": [
{
"sectionId": 241409387,
"courseId": 241409386,
"sectionName": "Section01"
}
],
"courses": [
{
"courseId": 241409386,
"courseName": "Tricon.Connect_01",
"showDiscipline": false
}
],
"users": [
{
"userId": 1000321061,
"firstName": "Ragu �������&^&",
"lastName": "+##)()Tricon �^^������",
"userType": "S"
}
],
"returnLMS": [
{
"returnUrl": "bb"
}
]
}
}
and i want to loop through suppose assignmet values
i am writing this in my template for looping model
{{#each obj in model.object}}
<tr>
{{#each assign in obj.assignments }}
<td>
{{assign.assignmentId} <br />{{assign.assignmentTitle}
</td>
{{/each}}
</tr>
{{/each}}
But i am not getting the output. My loop is getting failed at 1st line only.
i have to use these values to match some condition and display info.
This is now handled by using the {{each-in}} helper in the template. You can read more about it here but I will attempt an example that will work in your case
{{#each-in model.object as |key values|}}
<tr>
{{#each values as |assign|}}
<td>
{{assign.assignmentId} <br /> {{assign.assignmentTitle}
</td>
{{/each}}
</tr>
{{/each}}
Although your example looks more like you want to only loop through assignments because you are using assignment specific code inside the inner each so that would just look like this
{{#each model.object.assignments as |values|}}
<tr>
{{#each values as |assign|}}
<td>
{{assign.assignmentId} <br /> {{assign.assignmentTitle}
</td>
{{/each}}
</tr>
{{/each}}
If you did, however, want to loop through each of the keys and have different templates based on which key you are currently dealing with you could do something like this:
{{#each-in model.object as |key values|}}
{{#if (eq key 'assignments')}}
<tr>
{{#each values as |assign|}}
<td>
{{assign.assignmentId} <br /> {{assign.assignmentTitle}
</td>
{{/each}}
</tr>
{{/if}}
{{#if (eq key 'sections')}}
<tr>
{{#each values as |section|}}
<td>
{{section.sectionId} <br /> {{section.sectionName}
</td>
{{/each}}
</tr>
{{/if}}
{{/each}}
But of course that would be up to you and what you're trying to achieve with your application 😂 Also, by the way, this example makes use of ember-truth-helpers which is quite useful if you want to do things like those {{#if}} blocks in my example.
Based on the example JSON you've given, the following line is your problem:
{{#each obj in model.object}}
It seems that model.object is a Javascript object, not an array. The each loop only iterates or arrays (and possibly array-like objects), not arbitrary Javascript objects. If you want to iterate over the keys and values of an object, you'll have to create a computed property to do it.
Related
I have the following array with an object:
"customfield_10297": [
{
"self": "https://xxxxx.atlassian.net/rest/api/2/customFieldOption/10326",
"value": "Manual",
"id": "10326"
}
],
And I want to retrieve only the value key from it. Is there any way to do it with handlebars? I know only that I can iterate, but the whole array appears in report this way:
<br><b>Test Type:</b> {{#each data.jira.customfield_10297}}
{{#each this}}
<{{#key}}>{{this}}</{{#key}}>
{{/each}}
{{/each}}
I need to iterate the JSON data in the handlebars in {{#each}} statement.
This is the JSON data,
{
"no": 0,
"address": "Here",
"name": "There",
"members": [
{
"email": "test#test.com",
"name": "SH",
"sex": "F"
},
{
"email": "test2#test.com",
"name": "SH2",
"sex": "F"
}],
"diary": [
{
"ddate":"0820",
"dcheck":"y"
},
{
"ddate":"0821",
"dcheck":"n"
}]
}
and this is the Handlebars code.
I need to iterate 1st, 2nd, 3rd... object's properties in the members list.
I want to know what to put in instead of [0].
{{#each list}}
<tr>
<td><a href='bd-view.html?email={{members.[0].email}}'>{{members.[0].email}}</a></td>
<td>{{members.[0].name}}</td>
<td>{{members.[0].sex}}</td>
<td>{{name}}</td>
<td>{{diary.[0].dcheck}}</td>
<td><input type="checkbox"></td>
</tr>
{{/each}}
This is my first question in stackoverflow.
Hope to see someone answer this question.
Thanks a lot, cheers.
You can use the following:
{{#each members}}
<tr>
<td><a href='bd-view.html?email={{email}}'>{{email}}</a></td>
<td>{{name}}</td>
<td>{{sex}}</td>
<td>{{name}}</td>
{{#with (lookup ../diary #index)}}
<td>{{dcheck}}</td>
{{/with}}
<td><input type="checkbox"></td>
</tr>
{{/each}}
Using the #each to iterate your array, and the function #lookup to access to relative position of the array diary
I actually upvoted Matheus answer using the with lookup of the index. however I did it a different way where I manipulate the data before passing it in.
for (var i = 0; i < data.members.length; i++) {
data.members[i].dcheck = data.diary[i].dcheck;
}
here is a fiddle
http://jsfiddle.net/N2b5M/6750/
My angular controller is
$scope.dyna = [
{ "name": "parshuram", "age": 24 },
{ "name": "Tejash", "age": 26 },
{ "name": "Vinayak", "age": 25 }
];
My html
<table>
<tbody>
<tr ng-repeat="test in dyna">
<td>{{test.name}}</td>
<td>{{test.age}}</td>
</tr>
</tboody>
</table>
This works correctly, and outputs
Parshuram 24
Tejash 26
But if an another variable is added to my scope variable, I need to make changes in my html table:
$scope.dyna = [
{ "name": "parshuram", "age": 24 ,"void": true},
{ "name": "Tejash", "age": 26,"void" : false }
];
<table>
<tbody>
<tr ng-repeat= "test in dyna">
<td>{{test.name}}</td>
<td>{{test.age}}</td>
<!-- I don't want to have to add this, the columns should be added dynamically -->
<td>{{test.void}}</td>
</tr>
</tboody>
</table>
In that case, can the columns be generated dynamically, for example by getting all my object variables from the scope?
ng-repeat can loop over object key/values as well:
<table>
<tbody>
<tr ng-repeat= "test in dyna">
<td ng-repeat="(key, value) in test">
{{value}}
</td>
</tr>
</tbody>
</table>
However as noted in the docs linked above, there are a few limitations compared to an ng-repeat that works on arrays:
The JavaScript specification does not define the order of keys
returned for an object, so Angular relies on the order returned by the
browser when running for key in myObj. Browsers generally follow the
strategy of providing keys in the order in which they were defined,
although there are exceptions when keys are deleted and reinstated.
See the MDN page on delete for more info.
ngRepeat will silently ignore object keys starting with $, because
it's a prefix used by Angular for public ($) and private ($$)
properties.
The built-in filters orderBy and filter do not work with objects, and
will throw an error if used with one.
You should be able to do that with (key,value) iteration.
Would be nice to have fiddle to verify but would be something like:
<tr ng-repeat= "test in dyna">
<td ng-repeat="(key,value) in test">{{value}}</td>
</tr>
If at 'runtime', I don't know. Otherwise:
<div ng-controller="MyCtrl">
<table>
<tbody>
<tr ng-repeat= "test in dyna">
<td ng-repeat="key in objectKeys(test)">{{test[key]}}</td>
</tr>
</tbody>
</table>
</div>
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.dyna = [
{ "name": "parshuram", "age": 24 },
{ "name": "Tejash", "age": 26 },
{ "name": "Vinayak", "age": 25 }
];
$scope.objectKeys = function (object) {
var keys = Object.keys(object);
keys.splice(keys.indexOf('$$hashKey', 1))
return keys;
}
}
fiddle
HTML
<html>
<script src="library/angular.min.js"></script>
<script src="practice.js"></script>
<head>
</head>
<body ng-app="app">
<div ng-controller="test1" ng-bind-html="result">
</div>
</body>
</html>
Angularjs
angular.module('app',[]).controller('test1',['$scope','$compile','$sce',function($scope,$compile,$sce){
$scope.dyna = [
{ "name": "parshuram", "age": 24 },
{ "name": "Tejash", "age": 26 },
{ "name": "Vinayak", "age": 25 }
];
$scope.result="<table><tbody>";
for(var i=0;i<$scope.dyna.length;i++){
$scope.result+="<tr>";
for(var key in $scope.dyna[i])
if($scope.dyna[i].hasOwnProperty(key))
$scope.result+='<td>'+$scope.dyna[i][key]+'</td>';
$scope.result+="</tr>";
}
$scope.result+="</tbody></table>";
$scope.result=$sce.trustAsHtml($scope.result);
}]);
This is another way, creating html in controller.
just make it again put another ng-repeat in your loop for the test variable:
$scope.dyna = [{ "name": "parshuram", "age": 24 ,"void": true}, { "name": "Tejash", "age": 26,"void" : false }];
<table>
<tbody>
<tr ng-repeat= "test in dyna">
<td ng-repeat="t in test">{{test[t]}</td> // just like this
</tr>
</tboody>
</table>
I've been struggling to properly display my data in a table using Angular's ng-repeat. This should be really straightforward, as there are plenty of examples out there. I think the issue has something to do with namespacing, where I use self.all as the variable for my data in my js file.
HTML:
<div class="container">
<div ng-controller="TransferController as transfers">
<table st-table="transfers" class="table table-striped">
<thead>
<tr ng-repeat="row in transfers.all">
<td>Period: {{ row.period }}</td>
<td colspan="2">Upload Date: {{ row.uploadDate | date }}</td>
</tr>
<tr ng-repeat="code in transfers.all.sections">
<td colspan="3">Transfer Code: {{ code.transferCode }}</td>
</tr>
<tr>
</thead>
</table>
</div>
</div>
TransferController.js:
angular
.module("RssTransfers")
.controller("TransferController", ["$http", "$filter", function($http, $filter) {
var self = this;
self.all = [];
function getTransfers() {
$http
.get("http://localhost:3000/transfers/api")
.then(function(response) {
self.all = response.data.transfers;
})
}
console.log(self);
getTransfers();
}]);
Sample data:
[{
"period": 4,
"uploadDate": "2015-11-19T21:00:00.000Z",
"section":[{
"transferCode": 8675309,
"details": [
{
"voucherNumber": [34, 22],
"vendor": "jimmy",
"description": "blah ",
"amount": "t 45,555.00"
}
]
}]
},
{
"period": 4,
"uploadDate": "2015-11-19T21:00:00.000Z",
"section":[{
"transferCode": 45576543,
"details": [
{
"voucherNumber": 22,
"vendor": "Jonson",
"description": "trap music ",
"amount": "t 12,345.00"
}
]
}]
}]
I tried to put together a plunker but couldn't get Angular working for some reason. When I run this, period and uploadDate render on the page fine, but the row for transferCode does not render at all. Any help would be greatly appreciated; I imagine it's a simple mistake on my part.
EDIT:
My bad. I put incorrect sample data up initially. I did not include the section object. The correct model is up now.
You are iterating over section of the all.transfers array but all.transfers does not have any section property. Instead, each iterable of all.transfers has a section property.
So, in order to iterate over section property of each iterable, you have to place the second ngRepeat in the first ngRepeat like this:
<tr ng-repeat="row in transfers.all">
<td>Period: {{ row.period }}</td>
<td colspan="2">Upload Date: {{ row.uploadDate | date }}</td>
<td ng-repeat="code in row.sections">
{{code.transferCode}}
</td>
</tr>
I'm pulling in a json object, this is the result of a $.parseJSON output. I understand it needs a handler to help it but not to sure what belongs in the helper. Reading the other users questions, they seem to be able to jump through the next hoop due to having a constant key, unfortunately in my case it's always different.
Json output
[
{
"High blood pressure?": [
"no",
"string"
]
},
{
"Cancer?": [
"no",
"string"
]
},
{
"Asthma or a breathing disorder?": [
"no",
"string"
]
}
]
Loop
{{#each screen_data}}
<tr>
<td class="bold">{{this}}</td>
</tr>
{{/each}}
Results in
[Object object][Object object][Object object]......
It's because you've got an array of objects, and that's what you're telling your template to write out.. the object. It seems like you want to write out the only property on the root of the object, which is a question.
try this:
{{#each screen_data}}
<tr>
<td class="bold">{{this[0]}}</td>
</tr>
{{/each}}
That's a strange JSON structure you have there, I must say. Generally it's considered poor form to use the object property name as a carrier of data like that.
EDIT: I'd recommend changing that structure to something that better represents your data... like so:
[{
question: "High blood pressure?",
answers: [
"no",
"string"
]
},
{
questions: "Cancer?",
answers: [
"no",
"string"
]
},
{
question: "Asthma or a breathing disorder?",
answers: [
"no",
"string"
]
}]
Which would then mean your template would look like so:
{{#each screen_data}}
<tr>
<td class="bold">{{this.question}}</td>
</tr>
{{/each}}
You can try this fiddle below. It will give you all the keys from the JSON data
http://jsfiddle.net/tariqulazam/SjugS/
var data= [
{
"High blood pressure?": [
"no",
"string"
]
},
{
"Cancer?": [
"no",
"string"
]
},
{
"Asthma or a breathing disorder?": [
"no",
"string"
]
}
];
for (var key in data) {
for (var item in data[key]) {
alert(item);
}
}