ng-repeat repeating by letters wise - angularjs

I have multiple level json that need to show using ng-repeat but i am getting issues
JSON
$scope.product = {
"product": [
{
"name": "0001",
"tagline": "Scrub peached 60% cot 40% poly\r\ns/s v neck scrub uniform w/ 1 chest pkt"
}
],
"sizes": [
"XXL",
"XXXL",
"XS",
"XL",
"S",
"M",
"L"
],
"colors": [
{
"name": "WHITE",
"image": "/kalypso/commonsController.do?param=imageLoader&imageName=1239378389537_white1.JPG"
}
],
"images": [
{
"big": "/kalypso/commonsController.do?param=imageLoader&imageName=2010_08/1281620375516_UT01.jpg",
"small": [
"/kalypso/commonsController.do?param=imageLoader&imageName=2009_07/D0001-b.jpg"
],
"thumb": "/kalypso/commonsController.do?param=imageLoader&imageName=2010_08/1281620375516_UT01.jpg"
}
]
}
AngularJS
$scope.productsImages = $scope.product.images[0].thumb;
$scope.productsImgSmall = $scope.product.images[0].small;
$scope.productsImgBig = $scope.product.images[0].big;
$scope.productsColors = $scope.product.colors[0].cname;
$scope.productsColorsImages = $scope.product.colors[0].image;
$scope.productsSizes = $scope.product.sizes;
$scope.productsName = $scope.product.product[0].name;
$scope.productsTag = $scope.product.product[0].tagline;
$scope.productsPrice = $scope.product.product[0].price;
$scope.productsId = $scope.product.product[0].prdId;
console.log($scope.productsColors);
It is repeating the color name each word and if array length is zero I am getting duplicate error messages. Please help on this.
Error: [ngRepeat:dupes] http://errors.angularjs.org/1.3.0/ngRepeat/dupes?p0=color%20in%20productsColors&p1=string%3AT&p2=%22T%22

i would look into track by $index if you do not have a unique id on your json object
item in items track by $id(item)
or
item in items track by $index
if you want angular to deal with it

instead of array [i] value use like this
$scope.productsImages = $scope.product.images;
HTML
<ul>
<li ng-repeat="prd in productsImages">
{{prd.thumb}}
</li>
</ul>
use repeat function for all key
another Example
$scope.data.colors = $scope.product.colors
<ul>
<li ng-repeat="color in product.colors">
{{color.name}}
{{color.image}}
</li>
</ul>

Related

how to get data from an array in a json?

how can I get the information from this json to paint them in angular 10
{
"countries": [
{
"id": 1,
"name": "United States"
},
{
"id": 2,
"name": "India"
}
],
"states": [
{
"id": 1,
"countryId": 1,
"name": "Alabama"
},
{
"id": 2,
"countryId": 1,
"name": "Alaska"
}
]
}
for normal jsons I used this one, but that jeson has 2 arrays and it won't let me
return this.http.get<Country[]>("./assets/data.json");
Error trying to diff '[object Object]'. Only arrays and iterables are allowed
<!-- html -->
<div *ngFor="let item of countri">
{{item.id}}
</div>
model
export interface Country {
id: number;
name: string;
}
and my subscribe
countri: Country[] = [];
this.countriesService.getCountries().subscribe(
countri => {
this.countri = countri;
console.log(countri);
},
err => console.log(err)
);
Use any.
1st way:
return this.http.get<any>("./assets/data.json");
2nd way define an proper interface for your data.
export interface IRequest {
countries: ICourtry[],
states: IState[]
}
export interface ICourtry{
id:number;
name: string;
}
export interface IState{
id:number;
name: string;
countryId: number;
}
return this.http.get<IRequest>("./assets/data.json");
This mentioned error(Error trying to diff '[object Object]') are because you are using this json somewhere in your template but it has no values. Hope it will fix it or provide the template code also.
Error trying to diff '[object Object]'. Only arrays and iterables are allowed , this error usually comes when you try to iterate through ngFor with an Object instead of an Array.
If you are using ngFor,
list.component.ts
data={
"countries": [
{
"id": 1,
"name": "United States"
},
{
"id": 2,
"name": "India"
}
],
"states": [
{
"id": 1,
"countryId": 1,
"name": "Alabama"
},
{
"id": 2,
"countryId": 1,
"name": "Alaska"
}
]
}
list.component.html
<ul>
<li *ngFor="let item of data.countries">
{{item.name}}
</li>
</ul>
or
<ul>
<li *ngFor="let item of data.states">
{{item.name}}
</li>
As the error suggests, you are most likely trying to iterate over an object rather than an array. Also, since the data you fetch is asynchronous you may make use of the following code to avoid any errors. It makes use of the async pipe along with the safe(?) operator.
.ts
jsonData;
ngOnInit() {
this.jsonData = this.http.get('./assets/data.json');
}
template
<div *ngFor="let country of (jsonData | async)?.countries">
{{ country | json}}
</div>
<div *ngFor="let state of (jsonData | async)?.states">
{{ state | json}}
</div>

Consuming JSON Object in AngularJs

My Spring Rest Controller Endpoint is as below:
#CrossOrigin
#RequestMapping(value = "/getEverything", method=RequestMethod.GET)
public #ResponseBody MyItems getEverything(){
return myService.getEverything();
}
Below is MyItems class:
public class MyItems {
private Map<String, ArrayList<MyItem>> everything;
public Map<String, ArrayList<MyItem>> getEverything() {
return everything;
}
public void setEverything(Map<String, ArrayList<MyItem>> everything) {
this.everything = everything;
}
}
The rest call returns Json in below format:
{
"myItems": {
"Office": [
{
"field1": "Read a book",
"field2": "xyz",
"field3": true,
"field4": 1489795200000
},
{
"field1": "Write a program",
"field2": "abc",
"field3": false,
"field4": 1489881600000
}
],
"Home": [
{
"field1": "Watch a movie",
"field2": "pqr",
"field3": true,
"field4": 1489797800000
}
]
}
}
Here Office, Home are keys in the returned map.
How do I iterate or consume this JSon in AngularJS?
How do I get the key values ?
$http.get(REST_SERVICE_URI + 'toDo/getAllItems').then(function(response){
// what will go here ?
$scope.myItemLists = response.data;
});
I want myItemLists as a List containing objects with two properties:
1) Listname: This will be the key of the map returned.
2) List of Fields: This will be the list of object returned.
Thanks!
Try like this. use angular forEach loop
var app = angular.module('app', []);
app.controller('aCtrl', function($scope) {
$scope.myItems ={
"myItems": {
"Office": [
{
"field1": "Read a book",
"field2": "xyz",
"field3": true,
"field4": 1489795200000
},
{
"field1": "Write a program",
"field2": "abc",
"field3": false,
"field4": 1489881600000
}
],
"Home": [
{
"field1": "Watch a movie",
"field2": "pqr",
"field3": true,
"field4": 1489797800000
}
]
}
}
var keys = [];
var objectValues = [];
angular.forEach($scope.myItems.myItems,function(value,key){
keys.push(key);
objectValues.push(value);
})
console.log(keys);
console.log(objectValues);
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
<div ng-app="app" ng-controller="aCtrl">
</div>
you can store data in separate variable see below,
$http.get(REST_SERVICE_URI + 'toDo/getAllItems').then(function(response){
// what will go here ?
$scope.myItemLists = response.data;
$scope.itemListOfficeData = response.data.myItems.Office;
$scope.itemListHomeData = response.data.myItems.Home;
});
Or you can use nested data-ng-repeat for iterate data see below link for reference.
Nested ng-repeat
using ng-repeat inside another ng-repeat
While HJz answer is fine if what you want is to iterate through your json data in the controller, but if you simply want to present the data in a view, you can use ng-repeat directly on your json object like this:
<ul>
<li ng-repeat="(key, value) in myItems">{{key}}: {{value | json}}</li>
<ul>
which roughly turns into the following html (some values have been ignored for better readability):
<ul>
<li>Office: [{"field1": "Read a book"}, {"field1": "Read a book"}]</li>
<li>Home: [{"field1": "Watch a movie"}]</li>
<ul>
You can nest this ng-repeat directives, to further iterate through the values in your json data.
Alternatively, if all you need is an array of keys or an array of values, then JavaScript got functions you can use to extract those:
var keys = Object.keys(myItems);
// -> ['Office', 'Home']
var values = Object.values(myItems);
// -> [[{"field1": "Read a book"}, {"field1": "Write a program"}], [{"field1": "Watch a movie"}]]
You can flatten the nested object first and then iterate over it or you can use nested ng-repeat as shown below:
var app = angular.module('app', []);
app.controller('aCtrl', function($scope) {
var items = {
"myItems": {
"Office": [{
"field1": "Read a book",
"field2": "xyz",
"field3": true,
"field4": 1489795200000
},
{
"field1": "Write a program",
"field2": "abc",
"field3": false,
"field4": 1489881600000
}
],
"Home": [{
"field1": "Watch a movie",
"field2": "pqr",
"field3": true,
"field4": 1489797800000
}]
}
}
$scope.myItems = items.myItems;
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
<div ng-app="app" ng-controller="aCtrl">
<ul>
<li ng-repeat="(item, fields) in myItems">
{{item}}
<ul>
<li ng-repeat="field in fields">
{{field}}
<ul>
<li ng-repeat="(name, value) in field">
{{name}}:{{value}}
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>

Complicated sorting with tabs in ng-repeat?

I have the following JSON object:
$scope.projects = [
{
"_id": "58ab1cb6edf5430e9014e2bc",
"name": "Project 1",
"issues": [
{
"status": 0,
"name": "Hart Cummings"
},
{
"status": 1,
"name": "Kinney Leach"
},
{
"status": 2,
"name": "Blake Mclaughlin"
}
]
},
{
"_id": "58ab1cb6d87456482e0eec4a",
"name": "Project 2",
"issues": [
{
"status": 0,
"name": "Vargas Gordon"
},
{
"status": 1,
"name": "Bobbie Church"
},
{
"status": 2,
"name": "Pennington Fry"
}
]
},
{
"_id": "58ab1cb6d87456482e0eec4a",
"name": "Project 3",
"issues": [
{
"status": 0,
"name": "WWWWW"
},
{
"status": 1,
"name": "SFSF"
},
{
"status": 2,
"name": "Pennington Fry"
}
]
}
];
I use ng-repeat to display this object in template:
<div ng-app="app">
<div ng-controller="TodoListController">
<div ng-repeat="project in projects">
<br>
<br>
<div><b> {{project.name}}</b></div>
<div class="tabs">
<div style="display:inline" ng-click="sort(1, $index);">Active</div> |
<div style="display:inline" ng-click="sort(0, $index);">Deactivated</div>
</div>
_____________________________________
<div ng-repeat="issue in project.issues | filter: (filterObject.index | filterObject.status)">
<div>{{issue.name}}</div>
</div>
</div>
</div>
</div>
So, as you can see I have two nested ng-repeat.
Issue is:
When I click on any tab and call method sort() I need to sort issue in project.issues by status field.
This is real sample that I want to reach.
https://jsfiddle.net/at6kw67g/
Problem is in this code:
<div ng-repeat="issue in project.issues | filter:filterObject.index : {status : filterObject.status}">
Since the links should sort the issues of a specific project, you should pass the project as argument to your sort() function.
And JavaScript arrays have a sort() method, so just use it.
Since one link should sort issues in ascanding order, and the other one in descending order, you should also pass this information to your sort() function.
So it boils down to
$scope.sortIssuesByStatus = function(project, descending) {
project.issues.sort(function(issue1, issue2) {
var result = issue1.status - issue2.status;
if (descending) {
result = -result;
}
return result;
});
}
and
<div ng-repeat="project in projects">
<div class="tabs">
<button ng-click="sortIssuesByStatus(project, true)">Active</button>
<button ng-click="sortIssuesByStatus(project, false)">Deactivated</button>
</div>
<div ng-repeat="issue in project.issues">
<div>{{issue.name}} - {{ issue.status }}</div>
</div>
</div>
Here's a plunkr implementing it.

ng-repeat with recursive attributes object

I'm currently learning angularjs 1.5.0
I'm making a small sample with a complex json object, like this :
{
"Families":[
{
"Name": "A",
"Age": 1,
"Children": [
{
"Name": "B",
"Age": 2,
"Children":[
{
"Name": "C",
"Age": 3
},
{
"Name": "D",
"Age": 4
}
]
}
]
},
{
"Name": "X",
"Age": 5,
"Children":[
{
"Name": "Y",
"Age": 2
},
{
"Name": "Z",
"Age": 4
}
]
}
]
}
As you see, Families contains many members, each member has name, age and children. I want to list out this family tree , but one thing is difficult to me is : I don't know how many children can a member have therefore I don't know how to list them out by using ng-repeat.
Can anyone help me please ?
Thank you so much,
For displaying recursive json data arrays, use recursive templates in views.
create a template like below
<script type="text/ng-template" id="familyTree">
{{ family .name}}
<ul ng-if="family.children">
<li ng-repeat="family in family.children" ng-include="'familyTree'">
</li>
</ul>
</script>
and use ng-repeat in view like this to render the view
<ul>
<li ng-repeat="family in families" ng-include="'familyTree'"></li>
</ul>
sample fiddle
more details

Creating check box grid using ng-repeat

The Json structure,
[
{
"name": "module1",
"categories": [
{
"name": "cat1"
},
{
"name": "cat4"
}
]
},
{
"name": "module2",
"categories": [
{
"name": "cat3"
},
{
"name": "cat4"
}
]
},
{
"name": "module3",
"categories": [
{
"name": "cat1"
},
{
"name": "cat2"
},
{
"name": "cat4"
}
]
}
]
Using this Json structure, I need to display a grid of checkboxes as follows,
On click of any checkbox, I should be able to alert the corresponding category & module name. If each module has all four categories then I can easily use nested ng-repeat and display the structure (You can check it here. ). But here the number of categories differs for each module. Could you please suggest a way to implement this functionality?
Need to find the number of categories first and display it as the headers in the table
Display checkbox exactly at the right place
It is possible to have an ng-repeat iterate over the result of a function - in contrast to an array field in the scope - like this:
<tr ng-repeat="module in getAllModules()">
<td ng-repeat="cat in getAllCategories()">
<!-- display checkbox here if required -->
</td>
</tr>
I think it should be clear how to implement the two methods. However, you have to consider the performance overhead involved because the total set of modules and categories is calculated over and over again.
I think lex answer is corrrect. If I understood his solution right,the getAllCategories method is the interesting part. It has to return ALL categories, while getAllModules can still return your modules Array.
<tr ng-repeat="module in modules">
<td ng-repeat="cat in getAllCategories()">
<input type="check" ng-if="module.containsCat(cat)">
</td>
</tr>
with the containsCat method being something like
$scope.containsCat = function(module, cat){
for each(var moduleCat in module.categories ){
if(moduleCat.name === cat) return true;
}
return false;
}

Resources