ng-repeat through object with value as an array angular - javascript

I have an object with key value pairs that looks like this. You will see that the key has an array as its value.
$scope.testObj = {
"London":[
{"id":1,"city":"London","country":"GB","name":"Test1"},
{"id":4,"city":"London","country":"GB","name":"Test2"}
],
"Los Angeles":[
{"id":8,"city":"LA","country":"US","name":"Test3"}
]
}
I want to display the name next to the city in the front end using angular. To do this I have tried many approaches, and used track by $index, but cannot figure out how to get this working.
<div ng-repeat="(key, val) in jobsByCity track by $index">
{{key}}:{{val[$index].name}}
</div>
I have looked at this approach too, nesting ng-repeat
<div ng-repeat="(key, val) in testCity">
{{key}}
<div ng-repeat="test in val[$index].name">
{{test}}
</div>
</div>

Just use another ng-repeat to iterate over the value:
<div ng-repeat="(key, val) in jobsByCity">
<div ng-repeat="subValue in val track by $index">
{{key}}:{{subValue.name}}
</div>
</div>
Also note that your Los Angeles property needs to be in quotes, otherwise it isn't valid javascript.
See this jsfiddle

Related

how to show the grouping the array of objects using angular js

I have the array of object but I don't know how to group by the id as order. I want to show it numerical order like 1,2,3 using ng-repeat
$scope.arrayofobject=[{name:"testMachne","id":1},{name:"testComputer","id":2},{name:"testCalc","id":3},{name:"testMac","id":2},{name:"testMachne","id":3},{name:"testMachne","id":1}]
You can use the orderBy filter:
angular.module('app',[]).controller('mainCtrl', function($scope){
$scope.arrayofobject=[{name:"testMachne","id":1},{name:"testComputer","id":2},{name:"testCalc","id":3},{name:"testMac","id":2},{name:"testMachne","id":3},{name:"testMachne","id":1}];
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='app' ng-controller='mainCtrl'>
<div ng-repeat="json in arrayofobject | orderBy:'id' " ng-if='json.id !== 1'>
{{json.name}}
</div>
</div>

How to know if AngularJS filtered and limited lists lengths are the same

I'm trying to show an alert in case a filtered and limited list has elements not being shown. I'm looking for a good performing solution, as these lists will be really long.
Here is what I have from now:
<div class="list_item" ng-repeat="item in $ctrl.list | filter: $ctrl.responsiveFilter | limitTo: 6 as results track by $index">
<label ng-click="$ctrl.handle_list_click()">
<input type="checkbox" ng-model="item.checked">
<div class="fake_label" >
{{item.name}}
</div>
</label>
</div>
<div class="list_item too_many"
ng-repeat-end
ng-if="results.length > 6">
<div class="fake_label">
{{results.length}} matches... Please, filter out.
</div>
</div>
But the results contains the elements after being filtered and also limited. If I move the as results just before the limitTo, it just breaks.
The condition I want to detect show the alert would be: if the limited list's length and the filtered list's length are different, then show the alert.
I don't mind using something else, instead of the as results, just wonder if there is a way to detect that condition.
Edit: the problem right now is that results.length gives me the amount of elements after applying the limit, while what I need is the amount just after the filter, but before the limit. I know how to do this by deleting the limitTo sentence, but then there are too many results on the list...
var newapp = angular.module('someapp',[]);
newapp.service('limitcheck', [function(){
return {
checkLimit : function (arr) {
if (arr.length > 6) {
alert('The array has more than 6 entries');
}
}
};
}]);
newapp.filter('dummyfilter',['limitcheck',function(limitcheck){
return function (input) {
//do your filtering here
limitcheck.checkLimit(input);
return input;
}
}]);
newapp.controller('something', ['$scope',function(scope){
//This will trigger alert since it contains more than 6 entries
scope.alist = ['me','you','someone','anyone', 'noone','everyone','villain'];
//this will not
//scope.alist = ['me','you','someone','anyone', 'noone','everyone'];
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='someapp'>
<div ng-controller='something'>
<div ng-repeat='person in alist | dummyfilter | limitTo :6'>
{{person}}
</div>
</div>
</div>
I have tried and achieved the result by using a service and a filter combination
I hope this helps
The easiest way is to duplicate the repeat and use it to count the filtered elements. At first, I expected this to be quite slow but I'm really surprised of how fast it runs, probably because there is not really much DOM manipulation.
<div class="list_item" ng-if="false" ng-repeat="item in $ctrl.list | filter: $ctrl.responsiveFilter as count track by $index">
</div>
<div class="list_item" ng-repeat="item in $ctrl.list | filter: $ctrl.responsiveFilter | limitTo: 6 as results track by $index">
<label ng-click="$ctrl.handle_list_click()">
<input type="checkbox" ng-model="item.checked">
<div class="fake_label" >
{{item.name}}
</div>
</label>
</div>
<div class="list_item too_many"
ng-repeat-end
ng-if="count.length > results.length">
<div class="fake_label">
{{count.length}} matches... Please, filter out.
</div>
</div>
This way you have an ng-if hidden loop to count the filtered elements and another one to count and paint the limited list. All you have to do is to use these data to create the condition.

ng-model value inside ng-repeat not working

Having difficulty to assign ng-model values inside ng-repeat
So i am repeating this div with an array of json objects. I can print the 'ID' value of the object inside any element. But i can't use that as the ng-model value for the checkbox inside. I must be doing something wrong here. Any idea what that is?
Will really appreciate it if someone can take a look.
Here is a codepen of the issue. Code pen link
.
value for the model that assign to the checkbox is boolean whether it is true or false, unless you define the value. but again it is only 2 options value.
so, rather than using id as model attribute, you might change it to some attribute that could store boolean value. why not using 'isSelected'
<div ng-controller="quoteController" ng-app="MyApp" class="benefits-container">
<!-- benefits -->
<div class="benefit" ng-class="{'selected': pe.id}" ng-repeat="pe in policyEnhancementsArr | filter: {type:'optional'}">
<div class="top">
<md-checkbox ng-model="pe.isSelected" class="blue"></md-checkbox>
<h5 class="item">{{pe.name}}</h5>
<h5 class="prize">{{pe.loading}}</h5>
</div>
<div class="bottom">
<p>{{pe.limitDisplay}}</p>
</div>
</div>
</div>
then update some isSelected value:
...
{
"id": "PVC022",
"name": "NCD Protector",
"limit": null,
"limitDisplay": "N/A",
"desc": "<TBC>",
"type": "optional",
"loading": 0.0,
"isSelected": true
},
...
i have done exactly the same code the difference is the filter that you applied on ng-bind. try reading the article i suggest use ng-value.
whats the difference between ng-model and ng-value
try using ng-repeat and ng-model withing the same line.
instead of this
<div class="benefit" ng-class="{'selected': pe.id}" ng-repeat="pe in policyEnhancementsArr | filter: {type:'optional'}">
<div class="top">
<md-checkbox ng-model="pe.id" class="blue"></md-checkbox>
use this
<div class="benefit" ng-class="{'selected': pe.id}" ng-repeat="pe in policyEnhancementsArr | filter: {type:'optional'}"
ng-model="pe.id">
<div class="top">
<md-checkbox class="blue"></md-checkbox>

Manipulating data in angularjs/javascript

I have a an array of objects like this in angular:
$scope.data = [
{name:"John", group:"a"},
{name:"David", group:"a"},
{name:"Tom", group:"b"},
];
I want to present this data as something like this (in a template):
<h2>group a</h2>
John<br/>
David<br/>
<h2>groub b</h2>
Tom<br>
How would you suggest to do this? How can I go from the structure at the beginning to the structure at the end?
You could use grouby filter that would do group for you on basis of group property
Markup
<div ng-repeat="(key, value) in data | groupBy: 'group'">
<h1>group {{ key }}</h1>
<div ng-repeat="person in value">
{{ person.name }}
</div>
</div>

Pass parameter to Angular ng-include

I am trying to display a binary tree of elements, which I go through recursively with ng-include.
What is the difference between ng-init="item = item.left" and ng-repeat="item in item.left" ?
In this example it behaves exactly the same, but I use similiar code in a project and there it behaves differently. I suppose it's because of Angular scopes.
Maybe I shouldn't use ng-if, please explain me how to do it better.
The pane.html is:
<div ng-if="!isArray(item.left)">
<div ng-repeat="item in [item.left]" ng-include="'Views/pane.html'">
</div>
</div>
<div ng-if="isArray(item.left)">
{{item.left[0]}}
</div>
<div ng-if="!isArray(item.right)">
<div ng-repeat="item in [item.right]" ng-include="'Views/pane.html'">
</div>
</div>
<div ng-if="isArray(item.right)">
{{item.right[0]}}
</div>
<div ng-if="!isArray(item.left)">
<div ng-init = "item = item.left" ng-include="'Views/pane.html'">
</div>
</div>
<div ng-if="isArray(item.left)">
{{item.left[0]}}
</div>
<div ng-if="!isArray(item.right)">
<div ng-init="item = item.right" ng-include="'Views/pane.html'">
</div>
</div>
<div ng-if="isArray(item.right)">
{{item.right[0]}}
</div>
The controller is:
var app = angular.module('mycontrollers', []);
app.controller('MainCtrl', function ($scope) {
$scope.tree = {
left: {
left: ["leftleft"],
right: {
left: ["leftrightleft"],
right: ["leftrightright"]
}
},
right: {
left: ["rightleft"],
right: ["rightright"]
}
};
$scope.isArray = function (item) {
return Array.isArray(item);
}
});
EDIT:
First I run into the problem that the directive ng-repeat has a greater priority than ng-if. I tried to combine them, which failed. IMO it's strange that ng-repeat dominates ng-if.
It's a little hacky, but I am passing variables to an ng-include with an ng-repeat of an array containing a JSON object :
<div ng-repeat="pass in [{'text':'hello'}]" ng-include="'includepage.html'"></div>
In your include page you can access your variable like this:
<p>{{pass.text}}</p>
Pass parameter to Angular ng-include
You don't need that. all ng-include's sources have the same controller. So each view sees the same data.
What is the difference between ng-init="item = item.left" and ng-repeat="item in item.left"
[1]
ng-init="item = item.left" means - creating new instance named item that equals to item.left. In other words you achieve the same by writing in controller:
$scope.item = $scope.item.left
[2]
ng-repeat="item in item.left" means create list of scopes based on item.left array. You should know that each item in ng-repeat has its private scope
I am trying to display a binary tree of elements, which I go through recursively with ng-include.
I posted in the past answer how to display tree by using ng-include.
It might helpful: how-do-display-a-collapsible-tree
The main part here that you create Node with id wrapped by <scipt> tag and use ng-repeat:
<script type="text/ng-template" id="tree_item_renderer">
<ul class="some" ng-show="data.show">
<li ng-repeat="data in data.nodes" class="parent_li" ng-include="'tree_item_renderer'" tree-node></li>
</ul>
</script>
<ul>
<li ng-repeat="data in displayTree" ng-include="'tree_item_renderer'"></li>
Making a generic directive instead of ng-include is a cleaner solution:
Angular passing scope to ng-include
I am using ng-include with ng-repeat of an array containing string. If you want to send multple data so please see Junus Ergin answer.
See my code Snippet:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="">
<div ng-repeat="name in ['Sanjib Pradhan']" ng-include="'your_template.html'"></div>
<div ng-repeat="name in ['Chinmay Sahu']" ng-include="'your_template.html'"></div>
<script type="text/ng-template" id="your_template.html">
{{name}}
</script>
</div>

Categories

Resources