How to use ng-repeat in array of objects? - javascript

Do you have an idea ?
I tried to make an Array of arrays with ng-repeat like this :
jsfiddle example
function MyCtrl($scope) {
$scope.items =
[
{'adam1': [{id:10, content:test1}, {id:11, content:test2},
{id:12, content:test3}]},
{'adam2': [{id:20, content:test4}, {id:21, content:test5},
{id:30, content:test6}]},
{'adam1': [{id:10, content:xxx}]}
];
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>
<div ng-app ng-controller="MyCtrl">
<ul>
<li ng-repeat="(key, value) in items">{{key}}: {{value.content}}</li>
</ul>
</div>

One way to do that (fiddle):
<div ng-repeat="item in items">
<ul ng-repeat="(key, value) in item">
<li ng-repeat="obj in value">{{obj.content}}</li>
</ul>
</div>
That said you might want to rearrange the structure so as to avoid nested ng-repeat.

Your method of assigning variables works fine, but probably not as you're expecting: updated jsfiddle
The content item will not be available, as value is each object within the main array; you'll need to cycle through their properties (i.e. the adamX keys) to get the nested arrays.

Related

ng-repeat inside of ng-repeat- filters not working

I am displaying the ng-repeat content in two columns.
Using this code works fine:
<div class=storerow ng-repeat="store in stores track by $index" ng-if="$index%2==0">
<div ng-repeat="i in [$index,$index+1]" ng-if="stores[i]!=null" class="ngrepeatstore">
<div class="image-container" style="background-image: url({{stores[i].image}})" ng-click="tileClicked({{stores[i].id}})">
</div>
</div>
However, when I add a filter- it breaks the NG repeat and no content appears:
<div class=storerow ng-repeat="store in stores track by $index" ng-if="$index%2==0">
<div ng-repeat="i in [$index,$index+1] | filter: greaterThan('order', 0) | orderBy:'order'" ng-if="stores[i]!=null" class="ngrepeatstore">
<div class="image-container" style="background-image: url({{stores[i].image}})" ng-click="tileClicked({{stores[i].id}})">
</div>
</div>
the .js for greaterThan
$scope.greaterThan = function(prop, val){
return function(item){
return item[prop] > val;
}}
I tried adding the filter to the first ng-repeat- however that doesn't work as it just applies the filter to the overall content (ie if just one item is greatThan 0, it shows all items- not just the ones greater than 0).
This is because you're actually telling Angular to filter the property order on [$index, $index + 1], an array of two integers, which makes no sense.
I.E. With your delegate comparing index.prop > val, what you're really doing is comparing index['order'] > someValue.
This Plunker demonstrates: http://plnkr.co/edit/FkSrmZuuK4B1ToGNgAnq?p=preview You need to move filter:greaterThan(prop, val) up to the parent ng-repeat. Only there will your filter work.
<div ng-repeat="store in stores | filter:greaterThan2('id', 0) | orderBy:'name'" ng-if="$even">
{{store.name}}
<div ng-repeat="i in [$index, $index+1] | orderBy:angular.identity:true" ng-if="stores[i] !== null">
<strong>store.id</strong> {{i}}
</div>
</div>

Data bind over in array in knockoutjs

I have an array as follows:
self.arrayObj : Array[2]
>0:Object
>Display1
->InnerObjects
>__proto
>1:Object
>Display2
-->InnerObjects
My interntion is to display "Display1" and "Display2" which are strings
I am doing the html binding as follows:
<div data-bind="foreach: self.arrayObj">
<span data-bind="text:$data[0]"></span>
</div>
How can I iterate over the array and display only texts?
In case your array is just an array of strings you should do the following:
<div data-bind="foreach: self.arrayObj">
<span data-bind="text:$data"></span>
</div>
In case your array is an array of objects which have for example a property 'Name', which is a string, then you do it like this. Knockout knows you're inside the foreach so it knows which element you're at while looping.
<div data-bind="foreach: self.arrayObj">
<span data-bind="text:Name"></span>
</div>
I would like to answer my own question.
It is not a simple thing when we want to bind the object with dynamic keys and values in the UI using Knockout js. If we have the fixed keynames then its easy.
What I did was , converted the json object to 2-D array :
In the .js file
var 2Darray = jsonObject.map(function(val) {
var keyname = Object.keys(val)[0];
var value = val[keyname];
return [keyname,value];
});
In the html file , we can bind it two times in a loop:
<div data-bind:"foreach:2Darray">
<div data-bind:"foreach: $data">
<div data-bind:"text:$data[0]">
<div data-bind:"foreach: $data[1]">
<div data-bind:"text:$data.val">
</div>
</div>
</div>

ng-repeat gives me only one result

I'm using AngularJs to read the iTunes API. I want to get all the results in <entry> but so far I only get the first result:
<div class="container" ng-controller="appController">
<div class="item" ng-repeat="chart in charts">
<h2>{{chart.entry[$index]['im:name'].label}}</h2>
</div>
The result is im:name from entry[0]; when I replace $index with a number then I get the result as well, so clearly everything is loaded just fine.
Controller:
app.controller('appController', ['$scope', 'charts', function($scope, charts) {
charts.success(function(data) {
$scope.charts = data;
});
}]);
Loading JSON file:
app.factory('charts', ['$http', function($http) {
return $http.get('https://itunes.apple.com/us/rss/topsongs/limit=100/json')
.success(function(data) {
return data;
})
.error(function(data) {
return data;
});
}]);
I think you want to repeat over charts.feed.entry instead.
<div class="item" ng-repeat="entry in charts.feed.entry">
<h2>{{entry['im:name'].label}}</h2>
</div>
Edit: An explanation as to why this is charts.feed.entry and not charts.entry. From the question:
<div class="item" ng-repeat="chart in charts">
This looped through charts, which because it was an object and not an array, meant looping through its properties. There was only one, so there was one iteration, which assigned the single property, feed, to chart. Therefore:
chart.entry[$index]['im:name'].label
was equivalent to:
charts.feed.entry[$index]['im:name'].label
Based on your JSON structure, you're trying to loop over charts but it's not an array, it's just an object with an array called entry that has all the entries. So you should change your
<div class="item" ng-repeat="chart in charts">
<h2>{{chart.entry[$index]['im:name'].label}}</h2>
</div>
to
<div class="item" ng-repeat="entry in charts.feed.entry">
<h2>{{entry ['im:name'].label}}</h2>
</div>
Try changing it to
<div class="container" ng-controller="appController">
<div class="item" ng-repeat="chart in charts">
<div class="item" ng-repeat="entry in chart.entry">
<h2>{{entry['im:name'].label}}</h2>
</div>
</div>

Based on angular js

I have array called favouriteProducts=[deptName="",item:object(it contains product info like pid,name,brand)] for example
favouriteProducts[0]=deptName:"Fresh food"
item:object
productid:4356178
brand:brand_name
favouriteProducts[3]=deptName:"drinks"
item:object
productid:4356110
brand:brand_name
favouriteProducts[4]=deptName:"drinks"
item:object
productid:4356111
brand:brand_name
when i display the result the ouput is like (using ng-repeat in html)
fresh food
productid:4356178
fresh food
productid:4356179
drinks
productid:43561710
drinks
productid:43561711
But i want output in this way
fresh food
productid:4356178
productid:4356179
drinks
productid:43561710
productid:43561711
can anyone suggest me how to do this??
I want an array like
favouriteProducts[0]=deptName:"Fresh food"
item:object
0-->
productid:4356178
brand:brand_name
1-->productid:4356179
brand:brand_name
like this it should appear.
department name and respective products
You can add the items to the array in the following manner:
favouriteProducts[0]={deptName:"Fresh food", item: {productid:4356178,brand:brand_name};
favouriteProducts[3]={deptName:"drinks",item:{productid:4356110,brand:brand_name};
favouriteProducts[4]={deptName:"drinks", item:{productid:4356111,brand:brand_name}
Then just use ng-repeat in two div tags.
<div ng-repeat="dept in favouriteProducts.deptName">
<h3>{{dept}}</h3>
<div ng-repeat="item in dept.item">
{{item.productid}}
</div>
</div>
You can achieve the task in two ways.
Option 1
Use looping and collect all deptNames items under one criteria.
Options 2
Use angular-filter. A wonderful plugin and and a gift to angular developers.
Here is the JSFIDDLE
<h1>Option 1</h1>
<ul ng-repeat="product in newProducts"> {{product.key}}
<li ng-repeat="(key,value) in product.items">{{value.productid}}</li>
</ul>
<h1>Option 2</h1>
<ul ng-repeat="(key, value) in products |groupBy:'deptName'"> {{key}}
<li ng-repeat="(akey,avalue) in value">{{avalue.item.productid}}</li>
</ul>

How to Iterate over javascript Map using angular ng-repeat

I'm developing an Angualr application where we have a Map object (as shown below). The key and value of the map object (headerObj) are coming from user as input to the app,
var headerObj = new Map();
headerObj.set(key,value);
I'm iterating through them using foreach as shown below, the output is coming as expected
$scope.inputHeaders.forEach(function (headerkey, headervalue) {
console.log(headerkey, headervalue;
});
but I have to show this map values in UI, which again user can edit, so I have binded them
<li class="list-group-item" ng-repeat="header in inputHeaders">
<div ng-repeat="(key, value) in header">
{{key}} : {{value}}
</div>
</li>
I've googled and tried several ways, but nothing did help, so basically I've wanted to know how can I iterate over a map using forEach in angular?
Just to give more clarity my requirement is something like that: I need values to be passed to the server as key, value pair, only if I'm not wrong, suppose if I use object properties the key of the object will be fixed something like
{"key":"Content-Type","value":"application/x-www-form-urlencoded","$$hashKey":"003"}]
but my server is expecting something like
"Content-Type" => "application/x-www-form-urlencoded"
Created an plunkr edit http://plnkr.co/edit/t2g6Dl831HGyjD6uSdf3?p=preview
AngularJS 1.x does not know how to use Javascript iterators, so you'll have to convert the Map object to an Array first using Array.from().
Controller:
$scope.inputHeadersArray = Array.from($scope.inputHeaders);
View:
<li class="list-group-item" ng-repeat="header in inputHeadersArray">
{{header[0]}} : {{header[1]}}
</li>
you can use :
[...headerObj] or [...headerObj.entries()] to got two dimensions array. and iterate them.
or [...headerObj.keys()] and [...headerObj.values()] for regular array.
here are few changes in your code. http://plnkr.co/edit/gpc1mPsZrl2QVXbnWZKA?p=preview
app = angular.module('testDemo', []);
app.controller('submitCtrl',function($scope) {
$scope.header={};
$scope.inputHeaders=[];
$scope.addHeader = function() {
$scope.inputHeaders.push($scope.header);
$scope.header = {};
$scope.header.key='';
$scope.header.value='';
}
$scope.log=function(){
//alert('in log');
$scope.inputHeaders.forEach(function (key, value) {
console.log(key, value);
});
}
});
HTML:
<body ng-controller='submitCtrl'>
<div >
<input type="text" class="=form-control" ng-model="header.key" placeholder="Key">
<input type="text" class="=form-control" ng-model="header.value" placeholder="value">
<button class="btn btn-sucess" ng-click="addHeader()">Add</button>
<button class="btn btn-sucess" ng-click="log()">Log</button>
<div>
<ul class="list-group">
<li class="list-group-item" ng-repeat="header in inputHeaders">
<!-- need to to work on this logic -->
<div ng-show="inputHeaders.length>=1">
<input type="text" ng-model="header.value" />
<input type="text" ng-model="header.key" />
</div>
</li>
</ul>
</div>
</div>
</body>

Categories