I have the following json data, which comes from mongoDB:
{"list":
[{
"_id":"62f2fabd09de07c09f9e17e2",
"categoryName":"Web development",
"subcategories":[
{
"subcategoryName":"Backend",
"skills":["Nodejs", "Express"]
},
{
"subcategoryName":"Frontend",
"skills":["Css", "SASS"]
}
]
},
{
"_id":"62f33ba62ae52a71daa99a30",
"categoryName":"Cybersecurity",
"subcategories":[
{
"subcategoryName":"Red team",
"skills":["cURL","wfuzz"]
},
{
"subcategoryName":"Blue team",
"skills":["Cloudfare", "Burpsuite"]
}
]
}]
}
This is my angular scope, which gets the json data from the endpoint:
$scope.listSkills = function() {
$http.get("/showSkills").success(function(skills_from_database){
$scope.skills = skills_from_database.list;
})
}
And finally is my html/angular code
<div ng-repeat="category in skills">
<h1>{{category.categoryName}}</h1>
<div ng-repeat="subcategory in category.subcategories">
<hr>
<h2>{{subcategory.subcategoryName}}</h2>
<div ng-repeat="skill in category.subcategories">
<h5>{{skill.skills}}</h5>
</div>
</div>
</div>
The result is:
Category works
Subcategory works, but it gets all skills from the category, not only from the subcategory
Skills doesn't work, it gets the skills section but it should get all the arrays value, which I don't know how to do
Your inner loop needs to iterate over each member of subcategory.skills . I'm not sure why you are iterating again over the same object. (ng-repeat="subcategory in category.subcategories" and ng-repeat="skill in category.subcategories")
<div ng-repeat="skill in subcategory.skills">
{skill}
</div>
Related
I am defining a custom filter like so:
<div class="idea item" ng-repeat="item in items" isoatom>
<div class="section comment clearfix" ng-repeat="comment in item.comments | range:1:2">
....
</div>
</div>
As you can see the ng-repeat where the filter is being used is nested within another ng-repeat
The filter is defined like this:
myapp.filter('range', function() {
return function(input, min, max) {
min = parseInt(min); //Make string input int
max = parseInt(max);
for (var i=min; i<max; i++)
input.push(i);
return input;
};
});
I'm getting:
Error: Duplicates in a repeater are not allowed. Repeater: comment in item.comments | range:1:2 ngRepeatAction#https://ajax.googleapis.com/ajax/libs/angularjs/1.1.4/an
The solution is actually described here: http://www.anujgakhar.com/2013/06/15/duplicates-in-a-repeater-are-not-allowed-in-angularjs/
AngularJS does not allow duplicates in a ng-repeat directive. This means if you are trying to do the following, you will get an error.
// This code throws the error "Duplicates in a repeater are not allowed.
// Repeater: row in [1,1,1] key: number:1"
<div ng-repeat="row in [1,1,1]">
However, changing the above code slightly to define an index to determine uniqueness as below will get it working again.
// This will work
<div ng-repeat="row in [1,1,1] track by $index">
Official docs are here: https://docs.angularjs.org/error/ngRepeat/dupes
For those who expect JSON and still getting the same error, make sure that you parse your data:
$scope.customers = JSON.parse(data)
I was having an issue in my project where I was using ng-repeat track by $index but the products were not getting reflecting when data comes from database. My code is as below:
<div ng-repeat="product in productList.productList track by $index">
<product info="product"></product>
</div>
In the above code, product is a separate directive to display the product.But i came to know that $index causes issue when we pass data out from the scope. So the data losses and DOM can not be updated.
I found the solution by using product.id as a key in ng-repeat like below:
<div ng-repeat="product in productList.productList track by product.id">
<product info="product"></product>
</div>
But the above code again fails and throws the below error when more than one product comes with same id:
angular.js:11706 Error: [ngRepeat:dupes] Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater
So finally i solved the problem by making dynamic unique key of ng-repeat like below:
<div ng-repeat="product in productList.productList track by (product.id + $index)">
<product info="product"></product>
</div>
This solved my problem and hope this will help you in future.
What do you intend your "range" filter to do?
Here's a working sample of what I think you're trying to do: http://jsfiddle.net/evictor/hz4Ep/
HTML:
<div ng-app="manyminds" ng-controller="MainCtrl">
<div class="idea item" ng-repeat="item in items" isoatom>
Item {{$index}}
<div class="section comment clearfix" ng-repeat="comment in item.comments | range:1:2">
Comment {{$index}}
{{comment}}
</div>
</div>
</div>
JS:
angular.module('manyminds', [], function() {}).filter('range', function() {
return function(input, min, max) {
var range = [];
min = parseInt(min); //Make string input int
max = parseInt(max);
for (var i=min; i<=max; i++)
input[i] && range.push(input[i]);
return range;
};
});
function MainCtrl($scope)
{
$scope.items = [
{
comments: [
'comment 0 in item 0',
'comment 1 in item 0'
]
},
{
comments: [
'comment 0 in item 1',
'comment 1 in item 1',
'comment 2 in item 1',
'comment 3 in item 1'
]
}
];
}
If by chance this error happens when working with SharePoint 2010: Rename your .json file extensions and be sure to update your restService path. No additional "track by $index" was required.
Luckily I was forwarded this link to this rationale:
.json becomes an important file type in SP2010. SP2010 includes certains webservice endpoints. The location of these files is 14hive\isapi folder. The extension of these files are .json. That is the reason it gives such a error.
"cares only that the contents of a json file is json - not its file extension"
Once the file extensions are changed, should be all set.
Just in case this happens to someone else, I'm documenting this here, I was getting this error because I mistakenly set the ng-model the same as the ng-repeat array:
<select ng-model="list_views">
<option ng-selected="{{view == config.list_view}}"
ng-repeat="view in list_views"
value="{{view}}">
{{view}}
</option>
</select>
Instead of:
<select ng-model="config.list_view">
<option ng-selected="{{view == config.list_view}}"
ng-repeat="view in list_views"
value="{{view}}">
{{view}}
</option>
</select>
I checked the array and didn't have any duplicates, just double check your variables.
Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys.
Repeater: {0}, Duplicate key: {1}, Duplicate value: {2}
Example
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
<script src="angular.js"></script>
</head>
<body>
<div ng-app="myApp" ng-controller="personController">
<table>
<tr> <th>First Name</th> <th>Last Name</th> </tr>
<tr ng-repeat="person in people track by $index">
<td>{{person.firstName}}</td>
<td>{{person.lastName}}</td>
<td><input type="button" value="Select" ng-click="showDetails($index)" /></td>
</tr>
</table> <hr />
<table>
<tr ng-repeat="person1 in items track by $index">
<td>{{person1.firstName}}</td>
<td>{{person1.lastName}}</td>
</tr>
</table>
<span> {{sayHello()}}</span>
</div>
<script> var myApp = angular.module("myApp", []);
myApp.controller("personController", ['$scope', function ($scope)
{
$scope.people = [{ firstName: "F1", lastName: "L1" },
{ firstName: "F2", lastName: "L2" },
{ firstName: "F3", lastName: "L3" },
{ firstName: "F4", lastName: "L4" },
{ firstName: "F5", lastName: "L5" }]
$scope.items = [];
$scope.selectedPerson = $scope.people[0];
$scope.showDetails = function (ind)
{
$scope.selectedPerson = $scope.people[ind];
$scope.items.push($scope.selectedPerson);
}
$scope.sayHello = function ()
{
return $scope.items.firstName;
}
}]) </script>
</body>
</html>
If you call a ng-repeat within a < ul> tag, you may be able to allow duplicates. See this link for reference.
See Todo2.html
Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater: sdetail in mydt, Duplicate key: string: , Duplicate value:
I faced this error because i had written wrong database name in my php api part......
So this error may also occurs when you are fetching the data from database base, whose name is written incorrect by you.
My JSON response was like this:
{
"items": [
{
"index": 1, "name": "Samantha", "rarity": "Scarborough","email": "maureen#sykes.mk"
},{
"index": 2, "name": "Amanda", "rarity": "Vick", "email": "jessica#livingston.mv"
}
]
}
So, I used ng-repeat = "item in variables.items" to display it.
I'm creating an angular webapp, listing different cars in a sidebar and some information about the specific car in a informationbox.
The purpose is to show the right information in the box when clicking the different cars.
I have two different arrays(two API-endpoints), where the first array lists the car name, and the other one got the information about the car. But I have no idea how to connect the objects with the primary key and the foreign key, and how I'm supposed to output the right information after clicking the car.
app.js:
angular.module('myApp', [])
.controller('MyController', function($scope, $http) {
function fetch() {
$http({method : 'GET',url : 'http://*cars*'})
.success(function(data) {
$scope.cars = data;
});
$http({method : 'GET',url : 'http://*information*'})
.success(function(data) {
$scope.information = data;
});
}
fetch();
})
html:
<div id="sidebar">
<ul>
<li ng-repeat="name in cars">{{ name.displayName }}</li>
</ul>
</div>
For now all I have done is that I've fetched the data and outputed the cars in the sidebar. But now I've been googling and trying to connect the cars to the information with loops and functions for hours, but stil clueless.
Yes, I'm new to this. Any kind of help would be great! Thanks
You can deal with this with the ng-route. You can do something like :
In your route definition:
.when(/cars/:Id), {
name: 'cars',
templateUrl : 'ayourtemplate.html',
controller : 'yourCtrl'
})
In your html:
<div id="sidebar">
<ul>
<li ng-repeat="name in cars">{{ name.displayName }}</li>
</ul>
</div>
The Id will be your key tou will just have to match the right key in your $scope.information
It depends on what information those arrays contains.
If you're sure, that every element corresponds to other, you can just use $index in the html.
<li ng-repeat="name in cars">
{{ name.displayName }}
<p>{{ information[$index] }}</p>
</li>
However, if elements in array aren't ordered, you will have to check primary keys of objects in arrays. Let's assume, that data in arrays looks like this:
cars:
[
{ id: "1", name: "Carrera GT" },
{ id: "2", name: "DB 11" },
... and so on
]
information:
[
{ id: "2", info: "Lorem ipsum" },
{ id: "1", info: "Dolor sit amet" },
...
]
Then I'd suggest using loops and constructing new array using ids.
var carinfo = [];
cars.forEach(car => {
obj["id"] = car.id;
obj["name"] = car.name;
obj["info"] = ""; // Placeholder
info.forEach(c => {
if (c.id === car.id) {
obj["info"] = c.info;
}
});
carinfo.push(obj);
});
$scope.carInfo = carinfo;
Then you can use $scope.carInfo in the html file.
<li ng-repeat="car in carInfo">
{{ car.name }}
<p>{{ car.info }}</p>
</li>
I have an extremely hierarchical JSON structure as a scope variable in my AngularJS controller. I want to loop around different sections of that variable. I thought about using ng-init to specify where in the structure I am. Here is some code:
my_app.js:
(function() {
var app = angular.module("my_app");
app.controller("MyController", [ "$scope", function($scope) {
$scope.things = {
name: "a",
children: [
{
name: "a.a",
children: [
{ name: "a.a.a" },
{ name: "a.a.b" }
]
},
{
name: "a.b",
children: [
{ name: "a.b.a" },
{ name: "a.b.b" }
]
}
]
}
}]);
});
my_template.html:
<div ng-app="my_app" ng-controller="MyController">
<ul>
<li ng-init="current_thing=things.children[0]" ng-repeat="thing in current_thing.children>
{{ thing.name }}
</li>
</ul>
</div>
I would expect this to display a list:
a.a.a
a.a.b
But it displays nothing.
Of course, if I specify the loop explicitly (ng-repeat="thing in things.children[0].children") it works just fine. But that little snippet of template code will have to be run at various points in my application at various levels of "things."
(Just to make life complicated, I can get the current thing level using standard JavaScript or else via Django cleverness.)
Any ideas?
ng-init runs at a lower priority (450) than ng-repeat (1000). As a result, when placed on the same element, ng-repeat is compiled first meaning that the scope property created by ng-init won't be defined until after ng-repeat is executed.
As a result, if you want to use it in this manner, you'd need to place it on the parent element instead.
<div ng-app="my_app" ng-controller="MyController">
<ul ng-init="current_thing=things.children[0]">
<li ng-repeat="thing in current_thing.children>
{{ thing.name }}
</li>
</ul>
</div>
I have a nested JSON "object" called znanja that I want to display on my webpage. It will contain a number of values that I want to make into a list. Basically I'm building a portfolio and want to list my skills. So far I've managed to display the title, and the whole object, or by calling a specific one (for instance {{ znanje.ena }}), but I can't figure out how to display them without the attribute name. If I only call {{ znanje }}, I get them listed like in the JSON. Is there a angularJS directive I can do this with? I'm new to angular, so any help is appreciated.
my view:
<div ng-repeat="skill in skills">
<h1>{{ skill.title }}</h1>
<p ng-repeat="znanje in skill.znanja">{{ znanje }}</p>
</div>
my data:
$scope.skills = [
{
title: "Code Knowledge",
znanja : [{
ena : "Javascript",
dva : "HTML",
tri : "CSS",
stiri : "SASS"
}]
},
{
title: "Base Code Knowledge",
znanja : [{
ena : "Java",
dva : "PhP"
}]
},
{
title: "Data",
znanja : [{
ena : "MongoDB",
dva : "MySQL"
}]
}
];
PS: I've named the znanja attributes ena, dva, tri, stiri instead of 1, 2, 3, 4 to be able to call them in the html.
The object which you wanted to apply a loop is nothing but the 1st element in znanja array, so you should be specify skill.znanja[0] instead of skill.znanja.
By doing this you ng-repeat will iterate through each property of object and {{znanje}} will print the value of each property of znanja[0]
Markup
<div ng-repeat="skill in skills">
<h1>{{ skill.title }}</h1>
<p ng-repeat="znanje in skill.znanja[0]">{{ znanje }}</p>
</div>
It is possible to get ngRepeat to iterate over the properties of an
object using the following syntax:
<div ng-repeat="(key, value) in skill.znanja"> ... </div>
https://docs.angularjs.org/api/ng/directive/ngRepeat
In order to display the attributes you need a DOM element and a DOM element need a specific value to render so You have to manual at least for one iteration specifically call attributes.
How ever if you have any repetitions you can include it using ng-repeat like you have done.
That is if you want to display each attribute on the html page individually and later want to access it but if you just want to show as json object that will be as easy as passing the json
<div ng-repeat="skill in skills">
<h1>{{ skill.title }}</h1>
<p ng-repeat="(key,value) in skill.znanja[0]">{{key}} <b>:</b> {{value}}</p>
</div>
(tested) combined both znanja-object 0 and the value:
<div ng-repeat="skill in skills">
<h1>{{ skill.title }}</h1>
<p ng-repeat="(key, value) in skill.znanja[0] ">{{ value }}</p>
</div>
The simplest and best way to solve this issue is by changing your data structure. Simply remove the wrapping array around the lists you iterate on, turning them into object map:
$scope.skills = [
{
title: "Code Knowledge",
znanja : {
ena : "Javascript",
dva : "HTML",
tri : "CSS",
stiri : "SASS"
}
},
{
title: "Base Code Knowledge",
znanja : {
ena : "Java",
dva : "PhP"
}
},
{
title: "Data",
znanja : {
ena : "MongoDB",
dva : "MySQL"
}
}
];
If you did not intend to use that array in any way (all examples contain only one element), then there's no reason for having it there.
There's no need to change anything in your original ng-repeat that way.
I'm using a Moltin Cart which I want to loop through, so I can read it in Angular JS and then
I load the cart into a variable, which I'd like to <div ng-repeat-start="item in cart.contents"> and loop through the items in the cart.
The issue I'm having is really a pretty basic JavaScript issue, that if I console.log the cart.contents I get this:
Object{
33bb9f991617377b9b8333a79ca9ce2c: Object { ... cart contents... },
1ba14b804d0d81e49397b004e5f1c6d1: Object { ... cart contents... },
33bb9f991617377b9b8333a79ca9ce2c: Object { ... cart contents... },
}
Is there a way that I can fix this either in:
Laravel
Angular JS
or Classic JavaScript
I think what you're trying to do is this:
angular.module('myapp', [])
.controller('MyController', function($scope) {
$scope.objectOfObjects = {
"ASDF": { name: 'First', price: 100 },
"QWER": { name: 'Second', price: 200 },
"FGHJ": { name: 'Third', price: 500 }
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myapp">
<div ng-controller="MyController">
When iterating over an object of objects, there is no guarantee about the order:
<div ng-repeat-start="item in objectOfObjects">{{item.name}}</div>
<div ng-repeat-end>{{item.price}}<br/><br/></div>
</div>
</body>