ng-repeat on object angularjs - javascript

I have an object like this
Obj = {
"elements":[
{"name":"something","id":"v1-234"},
{"name":"somethingElse","id":"v1-239"}
],
"paging":{
"next" : "100",
"total": "2000"
},
"linked"={
"partners":[
{"id":"82","name":"A"},
{"id":"83","name":"B"}
],
"instructors":
[
{"id":"11232","name":"alex"},
{"id":"11432","name":"boob"}
]
}
}
I have equal items inside the elements array and the partner and instructors array. I have only placed 2 items just for display there could be many.
The Obj.elements[0] is related to Obj.linked.partners[0] and Obj.linked.instructors[0]. Similarly for the first,second,third ..... items as well.
How can I ng-repeat on this object such that I can show
Obj.elements[i] Obj.linked.partners[i] Obj.linked.instructors[i]
at a time in html template ?

If your elements, partners, and instructors arrays will always be the same length and you wanted to for example join together the names you could try something like this.
<div ng-repeat="element in Obj.elements">
{{element.name}} {{Obj.linked.partners[$index].name}} {{Obj.linked.instructors[$index].name}}
</div>
$index is used by Angular in a ng-repeat to keep track of its position when iterating through an object. Here is the documentation: ng-repeat

ng-repeat has the $index scoped variable:
<ANY ng-repeat="element in model.elements">
<span ng-bind="element.name"></span>
<span ng-bind="model.linked.partners[$index].name"></span>
<span ng-bind="model.linked.instructors[$index].name"></span>
</ANY>

Related

Filter Number in an angular object using limitto

I am using a angularjs filter method on an repeated array of items and trying to filter numbers with a limitTo filter. The result is not getting applied to the repeat in the DOM.
Here is the html
<div ng-controller="demo as d">
<input type="text" ng-model="d.test" ng-change="d.filterthis(d.test)"><br>
<div ng-repeat="item in d.items | limitTo:d.limitto track by $index">
<span ng-show="!item.show">{{item.myno}}</span> -
<span ng-show="!item.show">{{$index}} - {{item.mystr}}</span><br>
</div>
</div>
App.js filter function withing angularjs
this.filterthis = function(filter){
that.items.map(function(filter){
return function(obj){
obj.show=true;
if(obj.myno.toString().indexOf(filter) >-1){
console.log(obj);
obj.show=false;
}
return obj;
}
}(filter));
};
Items is a array like this
this.items = [{
show:false,
myno:10,
mystr:"test1"
}];
http://plnkr.co/edit/bTdlTpSeZuPyGpolXLEG
Having "show" as a key on your items, doesnt remove it from the ng-repeat, and so the limitTo filter will still return the items. Instead you should leverage the filter filter in the repeat like so
<input type="text" ng-model="d.search"><br>
<div ng-repeat="item in d.items | filter:{myno:d.search} | limitTo:d.limitto track by $index">
<span>{{item.myno}}</span> -
<span>{{$index}} - {{item.mystr}}</span><br>
</div>
Note that order is important here, if you limitTo and then filter you are only filtering the limit'ed result. You can change the key upon which you filter by changing {myno:d.search} to a different key, alternatively if you want to search the whole object, simply use d.search.
Updated Plunker

Use angularjs nested ng-repeat to construct complex table

I'm having trouble making proper table with nested ng-repeat.
What I wanted is this https://jsbin.com/razamagabo/1/edit?output
but I'm stuck at here https://plnkr.co/edit/d5voXIpzYL81sSl9BSY2?p=preview
I don't mind my markup is not table but I'm still stuck with div
<div class="row">
<div class="col-xs-6" ng-repeat="obj in data">
{{obj.date}}
<div ng-repeat="user in obj.users">
<br>
{{user.name}}
<br>
{{user.mark}}
</div>
</div>
</div>
In order for you to be able to display your data in the desired way, it will probably be easiest if you restructure your data in the JS before trying to render it.
It will be very complicated to try and match on the user names when they are in separate objects in the data array.
I would suggest processing your scope.data in the controller. (I'm assuming that you don't have much control on how you are receiving the data).
For example after you get your data...
$scope.data = [
{
date:'1-1-2016',
users:[
{
'name':'james',
'mark':18
},
{
'name':'alice',
'mark':20
}
]
},
{
date:'2-1-2016',
users:[
{
'name':'james',
'mark':60
},
{
'name':'alice',
'mark':55
}
]
}
]
var userData = {};
var possibleDates = [];
for (dataObj of Object.entries($scope.data)) {
for (userObj of dataObj) {
if ( !userData[userObj.name] ) {
userData[userObj.name] = {};
}
userData[userObj.name][dataObj.date] = userObj.mark;
if (dates.indexOf(dataObj.date) < 0) {
dates.push(dataObj.date);
}
}
}
$scope.users = userData;
$scope.dates = possibleDates;
this will give you an object like this on your scope
$scope.users = {
'james': {
'1-1-2016': 18,
'2-1-2016': 60
},
'alice': {
'1-1-2016': 20,
'2-1-2016': 55
}
};
$scope.dates = ['1-1-2016', '2-1-2016'];
This to me seems easier to structure for your template. Though this assumes each user has an entry for each date.
<div>
<div id='header-row'>
<div id='empty-corner></div>
<div class='date-header' ng-repeat='date in $scope.dates></div>
</div>
<div class='table-row' ng-repeat='{key, value} in $scope.users'>
<div class='user-name'>{{ key }}</div>
<div class='user-data' ng-repeat='date in $scope.dates>
{{ value[date] }}
</div>
</div>
</div>
As long as you apply inline-block styles to the rows/elements this should give you what you are looking for.
Though you can also think of ways to simplify your data even further. You could instead of having each user have an object where the dates are keys, you could just push the values into an array.
With your current data structure it is not possible to display it like you want. You are trying to loop over date-users objects in data array but then you want to display user from inside users array in separate rows. With ng-repeat you can loop through rows tr but not through columns. First you would need to map your data array to group elements that are supposed to be visible in 1 row into 1 object in array. Currently you have them in 2 separate objects:
James mark: 18 and James mark: 60.

AngularJs:Strange result in iterating key value pair

I have an array in angular as follows
$scope.arr={
"abc/xyz/../": [
"a1.txt",
"a2.txt",
"a3.txt"
],
"": [
"no-folder.txt"
],
"abc1/xyz/../": [
"a4.txt",
"a5.txt",
"a6.txt"
]
}
i want to iterate through this array and need to get the results as follows
"a1.txt",
"a2.txt",
"a3.txt"
and
"no-folder.txt"
and
"a4.txt",
"a5.txt",
"a6.txt"
i have tried as follows
<div ng-repeat="test in arr track by $index">
<h3 ng-repeat="(key, value) in test">
{{value}}
</h3>
</div>
but i am getting strange results as each character is coming as result .
can u pleas help.
update
please look to this fiddle
https://jsfiddle.net/771voyj6/8/
I don't know what you want to do but you can create your logic something like this it might work for you ,its some hardcoded work but change it accordingly
$scope.test = []
$scope.test.push(arr["abc1/xyz/../"]+arr[""]+arr["abc1/xyz/../"]);
Use test in ng-repeat .. :)
or you can do what i know with your code use ng-repeat like this for your code:
<div ng-repeat="test in arr">
<div ng-repeat="test2 in test">
{{test2}}
</div>
I don't know if Pankaj is right regarding the empty key value. But certainly your $scope.arr is not an array but an object.
As such your code should be:
<div ng-repeat="(key, value)in arr track by $index">
<h3 ng-repeat=" item in value">
{{item}}
</h3>
</div>
I suspect that the JSON you are getting is not valid JSON. In second second property of your object is ""(blank) which would be invalid JSON.
JSON
{
"abc/xyz/../": [
"a1.txt",
"a2.txt",
"a3.txt"
],
//in below line json has no key
"": [
"no-folder.txt"
],
"abc1/xyz/../": [
"a4.txt",
"a5.txt",
"a6.txt"
]
}
Update
Apology for having wrong conceptualization regarding JSON, above JSON is valid JSON (but technically JSON shouldn't have blank key). I tried the above code in Fiddle which is working fine.
Working Fiddle(Angular 1.4.8)
You need to replace your HTML code with the following:
<div ng-repeat="test in arr track by $index">
<div ng-repeat="item in test">
{{item}}
</div>
</div>
I am getting the result. Please check the following JSFiddle:
http://jsfiddle.net/akonchady/a25r1mm4/3/

Using splice on dynamic array in Angular repeater

I have an issue when trying to delete an object from an array using splice. I have an array that is dynamically created through a UI and stored in a scope variable called $scope.productAttributes.Products. This is an example of what it looks like...
[
{
"ProductLabel":"Net",
"Code":"ela",
"Site":"SITE1"
},
{
"ProductLabel":"Link",
"Code":"eli",
"Site":"SITE1"
},
{
"ProductLabel":"24-port managed PoE switch",
"Code":"24p",
"Site":"SITE2"
},
{
"ProductLabel":"Dedicated Firewall",
"Code":"ded",
"Site":"SITE2"
},
{
"ProductLabel":"Link",
"Code":"eli",
"Site":"SITE3"
},
{
"ProductLabel":"IPv4 Addresses",
"Code":"ip4",
"Site":"SITE3"
}
]
I then display that array in an angular repeater and group it by 'site' (which might be part of the problem)...
<div ng-repeat="(key, value) in productAttributes.Products | groupBy: 'Site'">
<strong>{{key}}</strong>
<div ng-repeat="site in value">
<h4>{{site.ProductLabel}}</h4>
<sapn href="" ng-click="deleteItem($index)" class="text-danger">Remove {{site.ProductLabel}}</span>
</div>
</div>
</div>
On the delete button I pass in the index of the object and use the splice function...
$scope.deleteItem = function (index) {
$scope.productAttributes.Products.splice(index, 1);
};
So the issue is that the $index is always zero (I noticed this from a console.log) as I mentioned that I think it might be down to the groupBy but I am not sure. anyone know whats going wrong? Thanks
UPDATE:
It would seem the problem is with the $index in the nested repeater. So if the json above the structure would be...
SITE1:
Product: Net - $index: 0
Product: Link - $index: 1
SITE2:
Product: 24-port - $index: 0
Product: Dedicated - $index: 1
SITE3:
Product: Link - $index: 0
Product: IPV4 - $index: 1
So if I try to delete the IPV4 product in SITE3, it removes the LINK product in Site1 as it has the same $index. any ideas how I can fix that?
We can not rely on $index as it does not contain the updated value after you remove an item from array.
Pass the object dynamically from UI and delete it from model using below code:
In Html:
<div ng-repeat="(key, value) in productAttributes.Products | groupBy: 'Site'">
<strong>{{key}}</strong>
<div ng-repeat="site in value">
<h4>{{site.ProductLabel}}</h4>
<sapn href="" ng-click="deleteItem(site)" class="text-danger">Remove {{site.ProductLabel}}</span>
</div>
</div>
</div>
In JavaScript:
$scope.productAttributes.Products.splice
($scope.productAttributes.Products.indexOf(site), 1);
This causes model to update with updates values in repeater and re-renders it on UI.
OK - I ended up doing it this way and it seems to work
$scope.deleteItem = function (item) {
var index = $scope.productAttributes.Products.indexOf(item);
$scope.productAttributes.Products.splice(index, 1);
};
So passing in the whole object seems to have worked. I'm not sure why.

sub ng-repeats, getting (checked) checkbox values in angular

I have some nested ng-repeats I am working with and the third level down is a grouping of checkboxes. Initially I am sent an array of options for the checkboxes so I do this:
<div class="fadingOptionsHere" ng-repeat="fading in fade.options">
<input type="checkbox" ng-model="fadingsHere" value="{{fading.id}}">{{fading.name}}
</div>
I am tyring to find a way to ONLY get the values of the selected checkboxes back. It would be super ideal if I could just replace the nested options array with an array of only the selected items, so I could just send the json object back like that.
This is the third level down of nesting so I'm having trouble tracking these guys. How would I be able to get only the selected values (as the fading.id) of the select boxes for each iteration of the ng-repeat?
I keep trying to reference the fadingsHere model with no success.
Thanks!
You can do this in this way.
In HTML do like below.
<ul>
<li data-ng-repeat="record in records">
<input type="checkbox" ng-model="selected[record.Id]"> {{record.Id}}
</li>
</ul>
And in controller you have to add selected property.
function MyCtrl($scope) {
$scope.records = [ { "Id": 1, }, { "Id": 2 }, { "Id": 3 } ];
$scope.selected = {};
$scope.ShowSelected = function() {
return $scope.selected
};
When you read the selected property you will get the selected list.
Demo
you could use checklist model directive like
<input type="checkbox" class="form-control"
checklist-model="transaction.jobData[attribute.key]"
checklist-value="checkBoxAttributes.code">

Categories

Resources