ng-repeat not working with Objects of Objects - angularjs

I have data in my object of objects but ng-repeat is not showing me anything my data is json Format like:
{
"0": [
{
"question": "How often is real property re-assessed (or revalued)?",
"id": 1,
"section": "Assessment",
"sectionId": 2,
"check": true,
"index": 0
},
{
"question": "How often is real property re-assessed (or revalued)?",
"id": 1,
"section": "Assessment",
"sectionId": 2,
"check": true,
"index": 0
},
{
"key": "Survey Meta Data"
}
],
"1": [
{
"question": "When are New Assessment Notices sent out?",
"id": 2,
"section": "Assessment",
"sectionId": 2,
"check": true,
"index": 1
},
{
"key": "Assessment"
}
]
}
and I want to display all question and key how can I achieve this I am trying something like this:
<div class="form-group" ng-repeat="data in viewQuestions">
<div ng-repeat="values[$index] in data ">
<label for="comment">{{values.questions}}</label>
</div>
<label for="comment">{{data.key}}</label>
<textarea class="form-control" rows="2" id="comment"></textarea>
</div>

remove the $index in your ng-repeat.
also, change the {{values.questions}} to {{values.question}}
<div class="form-group" ng-repeat="data in viewQuestions">
<div ng-repeat="values in data ">
<label >{{values.question}}</label>
</div>
<label for="comment">{{data.key}}</label>
<textarea class="form-control" rows="2" id="comment"></textarea>
</div>
Demo
angular.module("app",[])
.controller("ctrl",function($scope){
$scope.viewQuestions = {
"0": [
{
"question": "How often is real property re-assessed (or revalued)?",
"id": 1,
"section": "Assessment",
"sectionId": 2,
"check": true,
"index": 0
},
{
"question": "How often is real property re-assessed (or revalued)?",
"id": 1,
"section": "Assessment",
"sectionId": 2,
"check": true,
"index": 0
},
{
"key": "Survey Meta Data"
}
],
"1": [
{
"question": "When are New Assessment Notices sent out?",
"id": 2,
"section": "Assessment",
"sectionId": 2,
"check": true,
"index": 1
},
{
"key": "Assessment"
}
]
}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<div class="form-group" ng-repeat="data in viewQuestions">
<div ng-repeat="values in data ">
<label >{{values.question}}</label>
</div>
<label for="comment">{{data.key}}</label>
<textarea class="form-control" rows="2" id="comment"></textarea>
</div>
</div>

Proably you need this,
<div class="form-group" ng-repeat="(key,value) in viewQuestions track by $index">
<div ng-repeat="values in value ">
<label for="comment">{{values.question}}</label>
<label for="comment">{{values.key}}</label>
<textarea class="form-control" rows="2" id="comment"></textarea>
</div>
</div>
DEMO
var pegasusWebApp = angular.module('ReqWebApp', [])
pegasusWebApp.controller('ReqAppController', function ReqAppController($scope) {
$scope.viewQuestions = {
"0": [
{
"question": "How often is real property re-assessed (or revalued)?",
"id": 1,
"section": "Assessment",
"sectionId": 2,
"check": true,
"index": 0
},
{
"question": "How often is real property re-assessed (or revalued)?",
"id": 1,
"section": "Assessment",
"sectionId": 2,
"check": true,
"index": 0
},
{
"key": "Survey Meta Data"
}
],
"1": [
{
"question": "When are New Assessment Notices sent out?",
"id": 2,
"section": "Assessment",
"sectionId": 2,
"check": true,
"index": 1
},
{
"key": "Assessment"
}
]
};
});
<!DOCTYPE html>
<html ng-app="ReqWebApp">
<head>
<meta charset="UTF-8">
<title>New Request</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</head>
<body ng-controller="ReqAppController">
<div class="form-group" ng-repeat="(key,value) in viewQuestions track by $index">
<div ng-repeat="values in value ">
<label for="comment">{{values.question}}</label>
<label for="comment">{{values.key}}</label>
<textarea class="form-control" rows="2" id="comment"></textarea>
</div>
</div>
</body>
</html>

angular.module("Myapp",[])
.controller("Myctrl",function($scope){
$scope.viewQuestions = {
"0": [
{
"question": "How often is real property re-assessed (or revalued)?",
"id": 1,
"section": "Assessment",
"sectionId": 2,
"check": true,
"index": 0
},
{
"question": "How often is real property re-assessed (or revalued)?",
"id": 1,
"section": "Assessment",
"sectionId": 2,
"check": true,
"index": 0
},
{
"key": "Survey Meta Data"
}
],
"1": [
{
"question": "When are New Assessment Notices sent out?",
"id": 2,
"section": "Assessment",
"sectionId": 2,
"check": true,
"index": 1
},
{
"key": "Assessment"
}
]
}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.9/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<div ng-app="Myapp" ng-controller="Myctrl">
<div class="form-group" ng-repeat="(key,val) in viewQuestions track by $index">
<div ng-repeat="v in val ">
<label for="comment">{{v.question}}</label>
</div>
<label for="comment">{{val.key}}</label>
<textarea class="form-control" rows="2" id="comment"> </textarea>
</div>
</div>

Here is the JsFiddle link
HTML
<div ng-app="myApp">
<div ng-controller="ctrl">
<div ng-repeat="obj in data">
<div ng-repeat="item in obj">
<label ng-if="item.question">Question:{{item.question}}</label>
<label ng-if="item.key">Key: {{item.key}}</label>
<br>
<textarea ng-if="item.key" class="form-control" rows="2" id="comment">
</textarea>
<hr>
</div>
</div>
</div>
</div>
JS Code
var app = angular.module('myApp', []);
app.controller('ctrl', function($scope) {
$scope.data = {
"0": [{
"question": "How often is real property re-assessed (or revalued)?",
"id": 1,
"section": "Assessment",
"sectionId": 2,
"check": true,
"index": 0
}, {
"question": "How often is real property re-assessed (or revalued)?",
"id": 2,
"section": "Assessment",
"sectionId": 2,
"check": true,
"index": 0
}, {
"key": "Survey Meta Data"
}],
"1": [{
"question": "When are New Assessment Notices sent out?",
"id": 2,
"section": "Assessment",
"sectionId": 2,
"check": true,
"index": 1
}, {
"key": "Assessment"
}]
};
});
This will print out as you want.

Related

Nested array parsing

Hi I am parsing nested array but getting ReferenceError: player is not defined . I have state variable players which is json array as follows :
[
{
"game": "badminton",
"players": [
{
"name": "Hitesh",
"url": "https://i.imgur.com/aBpM49y.jpg",
"points": "1034.67",
"rank": "1",
"profile": "/hitesh"
},
{
"name": "Hitesh",
"url": "https://i.imgur.com/aBpM49y.jpg",
"points": "1034.67",
"rank": "1",
"profile": "/hitesh"
},
{
"name": "Hitesh",
"url": "https://i.imgur.com/aBpM49y.jpg",
"points": "1034.67",
"rank": "1",
"profile": "/hitesh"
},
{
"name": "Hitesh",
"url": "https://i.imgur.com/aBpM49y.jpg",
"points": "1034.67",
"rank": "1",
"profile": "/hitesh"
},
{
"name": "Hitesh",
"url": "https://i.imgur.com/aBpM49y.jpg",
"points": "1034.67",
"rank": "1",
"profile": "/hitesh"
}
]
},
{
"game": "football",
"players": [
{
"name": "Hitesh",
"url": "https://i.imgur.com/aBpM49y.jpg",
"points": "1034.67",
"rank": "1",
"profile": "/hitesh"
},
{
"name": "Hitesh",
"url": "https://i.imgur.com/aBpM49y.jpg",
"points": "1034.67",
"rank": "1",
"profile": "/hitesh"
},
{
"name": "Hitesh",
"url": "https://i.imgur.com/aBpM49y.jpg",
"points": "1034.67",
"rank": "1",
"profile": "/hitesh"
},
{
"name": "Hitesh",
"url": "https://i.imgur.com/aBpM49y.jpg",
"points": "1034.67",
"rank": "1",
"profile": "/hitesh"
},
{
"name": "Hitesh",
"url": "https://i.imgur.com/aBpM49y.jpg",
"points": "1034.67",
"rank": "1",
"profile": "/hitesh"
}
]
}
]
I am parsing it inside render function and creating a card based UI element for my view as follows :
render(){
// console.log(this.players);
var topplayers=[];
this.state.players.map(function(game,index){
topplayers.push(<div class="row" style={styles.row}>
<div class="col">
{game.game} Legend in Bangalore
</div>
</div>);
const row=<div class="row">;
topplayers.push({row});
game.players.map(function(player,index){
topplayers.push(<div class="col">
<div class="card">
<img class="card-img-top" src={player.url} alt="200-200" style={styles.image}/>
<div class="card-body">
<h4 class="card-title">{player.name}</h4>
<div >
<div style={styles.div}><img src="../../images/points.png" style={styles.rankimg}/>{player.points}</div>
<div style={styles.div}><img src="../../images/rank.png" style={styles.rankimg}/>{player.rank}</div>
</div>
View Profile
</div>
</div>
</div>)
}
)
const rowend=</div>;
topplayers.push({rowend})
}
)
return(
<div>
{topplayers}
</div>
);
}
But I am getting error ReferenceError: player is not defined . can someone help me where am I making mistake.
The problem is the const variables declared.
const row=<div class="row"> Here, div is marking start of html and
const rowend=</div>; here is ending tag.
So, everything in between is considered plain html. The map function is not behaving as a function but plain html. And that's why when player is put inside {}, javascript is trying to find the variable which doesn't exists.
Basically, in your code; everything written between <div class="row"> and </div> is considered html
To make it work, you need to restructure the code to something like this:
render(){
// console.log(this.players);
var topplayers=[];
this.state.players.map(function(game,index){
topplayers.push(<div class="row" style={styles.row}>
<div class="col">
{game.game} Legend in Bangalore
</div>
</div>
);
const row=<div class="row">
{game.players.map(function(player,index){
return (<div class="col">
<div class="card">
<img class="card-img-top" src={player.url} alt="200-200" style={styles.image}/>
<div class="card-body">
<h4 class="card-title">{player.name}</h4>
<div >
<div style={styles.div}><img src="../../images/points.png" style={styles.rankimg}/>{player.points}</div>
<div style={styles.div}><img src="../../images/rank.png" style={styles.rankimg}/>{player.rank}</div>
</div>
View Profile
</div>
</div>
</div>)
})
}
</div>;
topplayers.push(row)
})
return(
<div>
{topplayers}
</div>
);
}
Here, I have moved the game.players.map in {} wrapped in the <div class="row"> and </div>. This will make sure to work it like a function. Instead of pushing result into an array, I am directly returning values from the map function which will be injected between the required divs.
Hope you understand.
Please revert in case of any doubts

md-select with recursive options

I am trying to iterate through an array of categories with subcategories.
The problem. I have this array of categories:
$scope.categories = [{
"_id": 1,
"name": "Cat 1",
"categories": {
"_id": 11,
"name": "Cat 11",
"categories": {
"_id": 111,
"name": "Cat 111",
"categories": null
}
}
}, {
"_id": 2,
"name": "Cat 2",
"categories": null
}, {
"_id": 3,
"name": "Cat 3",
"categories": null
}];
As you can see, is an array of objects with subcategories, so I know that I need a recursive solution.
I need to show all the categories into a md-select (it is not necesary group it, but it will be great) and I am trying this:
<md-input-container class="md-block">
<label>Categories</label>
<md-select ng-model="selectedCategory">
<md-option ng-value="category._id" ng-repeat-start="category in categories">{{category.name}}</md-option>
<span ng-repeat-end ng-include="'subcategories'" ng-if="category.categories"></span>
</md-select>
</md-input-container>
<script type="text/ng-template" id="subcategories">
{{category.name}}
<md-option ng-value="category._id" ng-repeat-start="category in category.categories">{{category.name}}</md-option>
<span ng-repeat-end ng-include="'subcategories'" ng-if="category.categories"></span>
It works partially, but it is not the result expected.
What I want? Something like this
What I have? This code
Tell me if need more details.
Thanks
You can simply flatten your list and style elements by their nesting level.
angular
.module('app', ['ngMaterial'])
.controller('AppController', function($scope) {
$scope.categories = [{
"_id": 1,
"name": "Cat 1",
"categories": [{
"_id": 11,
"name": "Cat 11",
"categories": [{
"_id": 111,
"name": "Cat 111",
"categories": null
}]
}]
}, {
"_id": 2,
"name": "Cat 2",
"categories": null
}, {
"_id": 3,
"name": "Cat 3",
"categories": null
}];
$scope.flattenCategories = flatten($scope.categories, 0);
function flatten(categories, level) {
var flat = [];
for (var i = 0, n = categories.length, category; category = categories[i]; i++) {
flat.push({
_id: category._id,
name: category.name,
level: level
});
if (category.categories) {
flat = flat.concat(flatten(category.categories, level + 1));
}
}
return flat;
}
});
.subcategory-0 .md-text {
margin-left: 0;
}
.subcategory-1 .md-text {
margin-left: 8px;
}
.subcategory-2 .md-text {
margin-left: 16px;
}
.subcategory-3 .md-text {
margin-left: 24px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.11/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.11/angular-animate.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.11/angular-aria.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.11/angular-messages.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angular_material/1.1.4/angular-material.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/angular_material/1.1.0/angular-material.min.css">
<div ng-app="app" ng-controller="AppController">
<form name="myForm">
<md-input-container class="md-block">
<label>Categories</label>
<md-select ng-model="selectedCategory" name="myCategory">
<md-option ng-class="'subcategory-' + category.level" ng-value="category._id" ng-repeat="category in flattenCategories track by category._id">{{ category.name }}</md-option>
</md-select>
<!-- <pre ng-bind="flattenCategories | json"></pre> -->
</md-input-container>
</form>
</div>

AngularJS displays only elements that meet a certain condition

in my ng-repeat list I am displaying object elements from an object array $scope.toBuy:
$scope.toBuy=[
cookies={
name:'cookies',quantity:0,bought:false
},
water={
name:'water',quantity:0,bought:false
},
bananas={
name:'bananas',quantity:0,bought:false
},
milk={
name:'milk',quantity:0,bought:false
},
coconut={
name:'coconut',quantity:0,bought:false
}
];
and I initialize all element's bought field to false. How do I display in a ng-repeat list that only shows elements that have false value in their bought field? I tried this:
<ul>
<li ng-repeat="item in toBuy | filter:{item.bought===false }">Buy 10 {{item.quantity}} {{item.name}} <button class="btn btn-default" ng-click="btnOnClick(item.name)"> Bought</button></li>
</ul>
but none of the elements displayed when the page is loaded. If I removed the filter, the whole list displays, which means I applied the filter wrong.
You are using invalid javascript object syntax {item.bought===false }
Change to
ng-repeat="item in toBuy | filter:{bought:false }"
DEMO
Your JSON is not a valid JSON.
Try this valid JSON :
[{
"name": "cookies",
"quantity": 0,
"bought": true
}, {
"name": "water",
"quantity": 0,
"bought": true
}, {
"name": "bananas",
"quantity": 0,
"bought": true
}, {
"name": "milk",
"quantity": 0,
"bought": false
}, {
"name": "coconut",
"quantity": 0,
"bought": false
}]
Working demo :
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl', function($scope) {
$scope.toBuy=[{
"name": "cookies",
"quantity": 0,
"bought": true
}, {
"name": "water",
"quantity": 0,
"bought": true
}, {
"name": "bananas",
"quantity": 0,
"bought": true
}, {
"name": "milk",
"quantity": 0,
"bought": false
}, {
"name": "coconut",
"quantity": 0,
"bought": false
}];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<ul>
<li ng-repeat="item in toBuy | filter : {bought:false}">Buy 10 {{item.quantity}} {{item.name}} <button class="btn btn-default" ng-click="btnOnClick(item.name)"> Bought</button></li>
</ul>
</div>
Use ng-if (or ng-show):
<div ng-repeat="item in toBuy">
<div ng-if="item.bought===false">
Buy 10 {{item.quantity}} {{item.name}}
</div>
</div>
Try this:
<li ng-repeat="item in toBuy | filter:item.bought==false">
Or
<li ng-repeat="item in toBuy | filter:{bought:false}">
Will work, the second is a better way to achieve this.

angularjs - how to use ng-repeat element to get data from another set of data

Sorry, the titles is not clear at all, but I didn't really know a better title to explain what I'm tring to do.
Basically, I've this set of data:
$scope.data = [
{"id": 0, "name": "Testing name 0", "type": 1, "details": {"pinned": true, "link": [1,2]}},
{"id": 1, "name": "Testing name 1", "type": 0, "details": {"pinned": true, "link": [4]}},
{"id": 2, "name": "Testing name 2", "type": 0, "details": {"pinned": true, "link": []}},
{"id": 3, "name": "Testing name 3", "type": 0, "details": {"pinned": true, "link": []}},
{"id": 4, "name": "Testing name 4", "type": 1, "details": {"pinned": true, "link": [4,0]}},
{"id": 5, "name": "Testing name 5", "type": 1, "details": {"pinned": true, "link": []}},
{"id": 6, "name": "Testing name 6", "type": 1, "details": {"pinned": true, "link": [1,2,3,4]}}
];
and this repeater to display only the rooms with type 1:
<ion-list class="list">
<div ng-repeat="item in data">
<ion-item class="item item-stable" ng-if="item.type==1">
{{item.name}}
</ion-item>
<div ng-if="item.type==1" ng-repeat="(key, value) in item.details">
<div ng-repeat="linkID in value" ng-if="key == 'link'">
<ion-item class="item-accordion">
{{linkID}}
</ion-item>
</div>
</div>
</div>
</ion-list>
as you can see from the code above, I'm printing a top level item with the name of all "type:" 1, and as a sublevel, all off the values inside link: [].
So far so good, but the values inside link: [] are IDs of linked posts, and instead of 1,2 or 3 I'd like to print "Testing name 1", "Testing name 2", "Testing name 3" and so on...
I can't figure out the best way. All the data is there, but I just can't display it. I tried with another ng-if, but nothing. Any help?
here's an example: http://codepen.io/nickimola/pen/dMNawj?editors=1010
Instead of using ng-if better use filter.
Live example on jsfiddle.
angular.module('ExampleApp', [])
.controller('ExampleController', function($scope) {
$scope.data = [{
"id": 0,
"name": "Testing name 0",
"type": 1,
"details": {
"pinned": true,
"link": [1, 2]
}
}, {
"id": 1,
"name": "Testing name 1",
"type": 0,
"details": {
"pinned": true,
"link": [4]
}
}, {
"id": 2,
"name": "Testing name 2",
"type": 0,
"details": {
"pinned": true,
"link": []
}
}, {
"id": 3,
"name": "Testing name 3",
"type": 0,
"details": {
"pinned": true,
"link": []
}
}, {
"id": 4,
"name": "Testing name 4",
"type": 1,
"details": {
"pinned": true,
"link": [4, 0]
}
}, {
"id": 5,
"name": "Testing name 5",
"type": 1,
"details": {
"pinned": true,
"link": []
}
}, {
"id": 6,
"name": "Testing name 6",
"type": 1,
"details": {
"pinned": true,
"link": [1, 2, 3, 4]
}
}];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="ExampleApp">
<div ng-controller="ExampleController">
<ion-list class="list">
<div ng-repeat="item in data|filter:{type:1}">
<ion-item class="item item-stable">
{{item.name}}
</ion-item>
<div ng-repeat="linkID in item.details.link">
<ion-item class="item-accordion">
Lnked post--{{data[linkID].name}}
</ion-item>
</div>
<div ng-show="item.details.link.length==0">
<i>Nothing linked</i>
</div>
</div>
</ion-list>
</div>
</div>
Think that is what you expected?
<ion-content ng-app="ionicApp" ng-controller="MyCtrl">
<ion-list class="list">
<div ng-if="item.type==1" ng-repeat="item in data">
<ion-item class="item item-stable">
{{item.name}}
</ion-item>
<div ng-repeat="link in item.details.link">
<ion-item ng-if="data[link].name" class="item-accordion">
{{data[link].name}}
</ion-item>
<ion-item ng-if="!data[link].name" class="item-accordion">
Link not found: {{link}}
</ion-item>
</div>
<ion-item ng-if="item.details.link.length == 0">
Nothing
</ion-item>
</div>
</ion-list>
</ion-content>
You could load the links into the scope then reference them with the id (assuming they're in order).
<div ng-repeat="linkID in value" ng-if="key == 'link'">
<ion-item class="item-accordion">
{{links[linkID]}}
</ion-item>
</div>

iterate hasmap with ng-repeat. Hashmap with array as value

How can i iterate below JSON response from server using angularJS on UI using ng-repeat?
$scope.data = {
"Home Needs": [{
"id": 11,
"itemName": "PARLE G 500 Grams",
"itemPrice": 50,
"minSellPrice": 45,
"discount": 0,
"store": "Home Needs"
}],
"SRI SAI Store": [{
"id": 1,
"itemName": "PARLE G 500 Grams",
"itemPrice": 50,
"minSellPrice": 45,
"discount": 0,
"store": "SRI SAI Store"
}],
"Ashirwad": [{
"id": 10,
"itemName": "PARLE G 500 Grams",
"itemPrice": 50,
"minSellPrice": 46,
"discount": 0,
"store": "Ashirwad"
}]
}
Can anyone help me with a jsfiddle please or a pointer please?
thanks
Kindly check Jsfiddle
<div ng-app>
<div ng-controller="ClickToEditCtrl">
<p>Your Data:</p>
<ul ng-repeat="(key, value) in data">
name: {{key}}
<li ng-repeat="v in value">
{{v.id}},
{{v.itemName}},
{{v.itemPrice}},
{{v.minSellPrice}},
{{v.discount}},
{{v.store}}
</li>
</ul>
</div>
</div>
you can modified as u required. I hope this might help.

Resources