Is it possible to pass a variable in ng-repeat? - javascript

I'm new to angular and was wondering is it possible to replace firstP inside ng-repeat Directive with a variable? I'm using AngularJS v1.6.6
ng-repeat="option in people['firstP']"
var people = {
"firstP": [
"",
"James",
"Jack",
],
"SecondP": [
"",
"Bill",
"Bob",
]
};

is it possible to replace firstP inside ng-repeat Directive with a variable?
Yes it's possible to replace firstP with a variable, after all you are just using the normal javascript object bracket notation in Angular.
Solution:
If you are trying to display the people object contents dynamically, then you can do it like this:
<div ng-repeat="(key, value) in people">
<select>
<option ng-repeat="option in people[key]">{{option}}</option>
</select>
</div>
First you need to loop over the people object keys, then for each key take the relevant array, then loop over each array to display its contents.
Note:
Note that we can replace the people[key] with value directly in the ng-repeat so it becomes ng-repeat="option in value".
I just used people[key] for the question purpose, to answer your specific question.
Demo:
Here's a live working Plunker.

I think you have to assign people object to $scope variable in order to access people object in your html.
HTML
<html ng-app="myApp" ng-controller="testCtrl">
<ul>
<li ng-repeat="name in people[element]">{{name}}</li>
</ul>
</html>
JS
var app = angular.module('myApp', []);
var testCtrl = function($scope){
$scope.element = 'firstP';
$scope.people = {
"firstP" : [
"Jake",
"James",
"Jack",
],
"SecondP" : [
"",
"Bill",
"Bob",
]};
}
app.controller('testCtrl',['$scope',testCtrl]);
to check https://jsfiddle.net/0zk4mfak/6/

As per my understanding,
Define the array in your controller with the $scope variable:
In controller:
app.controller('nameCtrl', function($scope) {
$scope.people = { firstP: ['james', 'jack'] };
});
In Html:
<div ng-controller="nameCtrl">
<ul>
<li ng-repeat="option in people.firstP">{{option}}</li>
</ul>
</div>
Try this.Hope it helps..!

Your code looks suspiciously like it will populate a select (dropdown) box. If that is the case use ng-options for Angular 1:
Given this array of items on the $scope:
$scope.items = [{
id: 1,
label: 'aLabel',
subItem: { name: 'aSubItem' }
}, {
id: 2,
label: 'bLabel',
subItem: { name: 'bSubItem' }
}];
This will work:
<select ng-options="item as item.label for item in items track by item.id"
ng-model="selected"></select>
$scope.selected = $scope.items[0];
or ngFor in Angular 2 like in this answer:
<select name="selectmake" [(ngModel)]="makeListFilter">
<option *ngFor="let muscleCar of muscleCars" [ngValue]="muscleCar">
{{muscleCar.name}}
</option>
</select>

Related

ng-repeat do not work on arrays of length > 23 [duplicate]

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.

Select multiple element affecting properties of the objects it's populated from

So I have this array people
people = [{name: "John",hair: false},{name: "James": hair: false}]
I have a select element with the multiple attribute that is populated from
<select ng-model="people" multiple
ng-options="person.hair as person.name for person in people">
</select>
What I'm trying to achieve is when the user selects one or more items from this select element it will set the hair property of the selected item(s) to true.
Now what's happening is I select an item and it sets people to false, which makes sense. The select needs an ng-model for ng-options to work. If I set it to something else nothing gets changed on people
I've tried putting a function in ng-change and throwing the ng-model I set to it but that won't make the selection 'highlighted' in the select multiple element. I know there are more practical ways to do this but I'd like to figure out how to use the select multiple if I could.
Here's one way to do it:
<select ng-model="hairyPersons" multiple
ng-change="updatePeople(hairyPersons)"
ng-options="person as person.name for person in people">
</select>
$scope.updatePeople = function(selects) {
$scope.people.forEach(x => x.hair=false);
selects.forEach(x => x.hair=true);
};
The ng-model variable needs to be different than the ng-options array.
The DEMO
angular.module("app",[])
.controller("ctrl", function($scope) {
$scope.people = [
{name: "John", hair: false},
{name: "James", hair: false},
{name: "Mary", hair: false},
{name: "Fred", hair: false},
];
$scope.updatePeople = function(selects) {
$scope.people.forEach(x => x.hair=false);
selects.forEach(x => x.hair=true);
};
})
<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="app" ng-controller="ctrl">
<select ng-model="hairyPersons" multiple
ng-change="updatePeople(hairyPersons)"
ng-options="person as person.name for person in people">
</select>
<div ng-repeat="p in people">
{{p.name}} hair={{p.hair?'TRUE':false}}
</div>
<h3>hairyPersons</h3>
<ol>
<li ng-repeat="h in hairyPersons">{{h.name}}</li>
</ol>
</body>
Another way to do it is with a list of checkboxes:
<div ng-repeat="p in people">
<input type="checkbox" ng-model="p.hair">{{p.name}}<br>
</div>
The ng-model directives operate directly on objects in the people array.
All the unchecked boxes set hair: false; all the checked boxes set hair: true on their respective objects.

AngularJS ngOption does not display datas

I'd like to use ng-options for my select using AngularJS but it seems not working as I'd like...
Below you can see javascript code, which contain from creating array
and also view, where ng-options are using.
var vm = this;
vm.selectedUser;
vm.userDatas = [
{ id: 1, name: "Ruslan", surname: "Poltayev" },
{ id: 2, name: "Handor", surname: "Ten" }
];
<div id="page-content-wrapper"
data-ng-controller="TableShowCtrl as t">
<select data-ng-model="t.selectedUser"
data-ng-options="item.name for item in t.userDatas track by item.id">
</select>
</div>
I have this results
enter image description here
You need to declare the elements to display the different options. To display options using the name property you can use this:
<select ng-model="selected.user">
<option ng-repeat="item in t.userDatas">{{ item.name }}</option>
</select>
<!-- display selected user -->
{{ t.selected.user | json }}
Check this.
<body ng-app="Sample">
<h1>Sample Angular controller</h1>
<div ng-controller="Ctrl">
<div id="page-content-wrapper" >
<select ng-model="t.selectedUser" ng-options="item.name for item in usrDatas ">
</select>
</div>
</div>
</body>
Script:
// Code goes here
var app = angular.module("Sample",[]);
app.controller("Ctrl", function($scope){
var vm = this;
vm.selectedUser;
$scope.userDatas = [ { id: 1, name: "Ruslan", surname: "Poltayev" },
{ id: 2, name: "Galym", surname: "Kariev" }];
})
Working Demo at Plnkr

AngularJS: I clearly do not understand the use of ng-init

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>

How to index variables in html using angularjs

I am new to angularjs and still learning the language.
I created a select box in an html and I want to populate it with a variable in my controller.
I am able to get the variable in the html using {{variablename}}, but I am not able to get the sub objects within it.
Please see my code here.
You can see that it displays "repeatSelect" in the html but if i try to index an object within it, it doesn't show.(getID is always empty)
Controller has a $scope variable as follows
controller('ExampleController', ['$scope', function($scope) {
$scope.repeatSelect = null;
$scope.data = {
availableOptions: [
{id: '1', name: 'Option A'},
{id: '2', name: 'Option B'},
{id: '3', name: 'Option C'}
],
};
}]);
In the html code,
<tt>repeatSelect = {{repeatSelect}}</tt><br/>
<tt>getID = {{repeatSelect.id}}</tt><br/>
repeatSelect works fine, but repeatSelect.id doesn't.
Please guide
Use ng-options built in directive instead https://docs.angularjs.org/api/ng/directive/ngOptions.
It is designed specifically to work with HTML select lists and has plenty of powerful options.
<div ng-controller="ExampleController">
<label> Repeat select: </label>
<select ng-options="option as option.name for option in data.availableOptions track by option.id" ng-model="repeatSelect"></select>
<hr>
<tt>repeatSelect = {{repeatSelect}}</tt><br/>
<tt>getID = {{repeatSelect.id}}</tt><br/>
</div>
Please see plunkr here: http://plnkr.co/edit/kIcH5fF7suhN0rhVDez8?p=preview

Categories