Why this ng-repeat does not loop all the values? - javascript

Even more values are pushed into the array:
.controller('MyCtrl', function($scope) {
$scope.mottos = [];
$scope.mottos.push('One');
$scope.mottos.push('Two');
$scope.addMotto = function(motto) {
$scope.mottos.push(motto);
}
});
and
<span ng-repeat="motto in mottos"> {{motto}} </span>
ng-repeat does not show all elements as expect: codepen, why?
...
HTML
<ion-content>
<button class="button button-positive" ng-click="addMotto('More')">
<i class="icon ion-quote"> Click me to add more ...</i>
</button>
<div class="card item-text-wrap">
<div class="item">
{{mottos.length}}
<span ng-repeat="motto in mottos"> {{motto}} </span>
</div>
</div>
</ion-content>

From the documentation:
By default, ngRepeat does not allow duplicate items in arrays. This
is because when there are duplicates, it is not possible to maintain a
one-to-one mapping between collection items and DOM elements.
If you do need to repeat duplicate items, you can substitute the
default tracking behavior with your own using the track by
expression.
So if you update your code as follows, things work as expected:
<span ng-repeat="motto in mottos track by $index">
{{motto}}
</span>

Instead of this
<span ng-repeat="motto in mottos"> {{motto}} </span>
try something like this
<span ng-repeat="motto in mottos track by $index"> {{motto}} </span>
you can see this in more detail on this page

Your issue occurs because ng-repeat does not have a unique identifier for each object. If you change the code to append the length on each object (more1, more2, more3, etc since lengths/indexes are unique) it works fine. I've seen a similar issue in WPF.

because you need to use $track by
he solution is actually described here: http://www.anujgakhar.com/2013/06/15/duplicates-in-a-repeater-are-not-allowed-in-angularjs/
http://codepen.io/anon/pen/doRKWY
<span ng-repeat="motto in mottos track by $index"> {{motto}} </span>

Related

Don't repeat button in ng-repeat

I'm using ng-show option in AngularJS.
<button ng-click="removeFilter();">
<span ng-repeat="cat in ctrl.getCategories()" ng-show="ctrl.filter[cat]" class="fa fa-close"></span></button>
This works very good but if I click second item, this div add another one but one button is enough for me.
How can I do that? Thanks.
Just place it outside
<button ng-click="removeFilter();"> </button>
<span ng-repeat="cat in ctrl.getCategories()" ng-show="ctrl.filter[cat]" class="fa fa-close"></span>

ng-repeat inside ng-repeat not working in angularjs app

I am using two ng repeats but the second one it doesnt display. Let me show you my view :
<div class="post" ng-repeat="user in users | orderBy:'username':false" ng-class-odd="'odd'" ng-class-even="'even'">
<p>{{user.username}}</p>
<small><a ng-click='gotomessages(user.username)' class="btn btn-default">go</a></small>
<small class="pull-right"> Message</small>
<div ng-repeat="message in messages[$index]">
<p>{{message.name}}</p>
</div>
</div>
the $index is the one of the first ng-repeat. Is it possible to use it like i did ? In anyway the second ng repeat doesnt work can you help
Just use $parent.messages[$index] instead of messages[$index] in the second ng-repeat

ng-repeat repeats the div the directive is on

I have the following code:
<div ng-repeat="item in selectedCategory">
<div class="repertoire-composer">
<div data-toggle="collapse" data-target="#compositions{{$index}}"
class="repertoire-composer-title">
<span class="fa fa-chevron-right"></span>
{{item.composer}}
<span class="fa fa-plus"></span>
</div>
<div id="compositions{{$index}}" ng-repeat="composition in item.compositions" class="repertoire-compositions collapse">
<div class="repertoire-composition">
{{composition}}
<span class="fa fa-remove" title="Remove"></span>
</div>
</div>
</div>
</div>
So what I basically want is to have a tree of multiple .repertoire-composer divs, each of which with one or many child .repertoire-composition inside its .repertoire-compositions div. So in the second repeat, angular should create one or more .repertoire-composition divs. However, what it seems to do is create more divs of the one the directive is on. Hope I've been explicit enough, here's the unwanted result:
So basically, why is my .repertoire-compositions div getting duplicated?
EDIT:
I was misunderstanding ng-repeat. This is the intended behaviour of it: to repeat the element the directive is on. Thanks for the clarification.
.repertoire-compositions is not being duplicated it's being actually ng-repeated by this part of your template:
<div id="compositions{{$index}}" ng-repeat="composition in item.compositions" class="repertoire-compositions collapse">
I guess it's because of the second ng-repeat on item.compositions, can you provide a set of data ?
I'm not sure but you can try this in the inner repeater:
<div id="compositions{{$index}}" class="repertoire-compositions collapse">
<div class="repertoire-composition" ng-repeat="composition in item.compositions">
{{composition}}
<span class="fa fa-remove" title="Remove"></span>
</div>
</div>

Icon in ionic list is not clickable

I have a list in my ionic project with some icons that I want to click. But I cannot get the click to be picked up either by the htmll onclick() or by the AngularJS ng-click. My html looks like this:
<ion-view view-title="CUES - WATCH LIST">
<ion-content>
<div class="notification-message col-80" ng-hide="hideNotificationMessage" ng-click="hideNotificationMessage=true" ng-bind-html="messageContents"></div>
<ion-list>
<ion-item ng-repeat="watchlistitem in watchlist" href="#/app/trailer/{{watchlistitem.id}}">
<div class="watchlist-movie-thumb">
<img class="movie-thumb-image" src="{{watchlistitem.picture}}">
</div>
<div class="col-75 watchlist-title-genre-container">
<div class="watchlist-movie-title">
{{watchlistitem.title}}
</div>
<div class="watchlist-movie-genres">
{{watchlistitem.genres}}
</div>
</div>
<a class="item-icon-right" onclick="alert('you clicked me');" ng-click='remove_movie()'>
<i class="icon ion-trash-a" style="color:black;padding-top:40px"></i>
</a>
<a class="item-icon-right">
<i class="icon ion-ios-upload-outline" style="color:black;padding-bottom:40px;"></i>
</a>
</ion-item>
</ion-list>
</ion-content>
</ion-view>
The fact that even the onclick() doesn't pick up the click is very odd. I have tried changing the z index to 9999 but that has made no difference.
I stumbled across an answer by trying every html mod I could think of.
This is a bit of a bodge but works without compromising the layout.
I simply added a margin-right style to the tag as follows:
<a class="item-icon-right">
<i class="icon ion-ios-upload-outline" style="margin-right:-2px;color:black;padding-bottom:40px;" ng-click='remove_movie()'></i>
</a>
It doesn't seem to matter with respect to fixing the click problem what value I give the margin-right as long as it is there. It does though alter the layout as you would expect.

AngularJS ng-repeat through json array doesnt work in second array

I'm trying to do a ng-repeat over a json array. I'm able to do the first iteration of 'event in calendar'. But I'd not have to manually iterate through each number.
This works:
<div ng-repeat="event in calendar">
{{event[0].custom_fields.location[0]}}
{{event[0].custom_fields.price[0]}}
{{event[1].custom_fields.location[0]}}
{{event[1].custom_fields.price[0]}}
{{event[2].custom_fields.location[0]}}
{{event[2].custom_fields.price[0]}}
</div>
I've tired doing two ng-repeats and it fails. How do I fix this?
<div ng-repeat="event in calendar">
<div ng-repeat="custom_fields in event.custom_fields">
{{custom_fields.location[0]}}
{{custom_fields.price[0]}}
</div>
</div>
According to your first example, event is the array, not the custom_fields property. Iterate it instead.
<div ng-repeat="events in calendar">
<div ng-repeat="event in events">
{{event.custom_fields.location[0]}}
{{event.custom_fields.price[0]}}
</div>
</div>

Categories