Reputation: 28448
I need to create a comma-separated list of items:
<li ng-repeat="friend in friends">
<b ng-repeat="email in friend.email">{{email}}{{$last ? '' : ', '}}</b>...
</li>
According to the AngularJS documentation, no control flow statements is allowed in expressions. This is why my {{$last ? '' : ', '}}
does not work.
Is there an alternative way to create comma-separated lists?
EDIT 1
is there something simpler than:
<span ng-show="!$last">, </span>
Upvotes: 181
Views: 133137
Reputation: 25
I like simbu's approach, but I ain't comfortable to use first-child or last-child. Instead I only modify the content of a repeating list-comma class.
.list-comma + .list-comma::before {
content: ', ';
}
<span class="list-comma" ng-repeat="destination in destinations">
{{destination.name}}
</span>
Upvotes: 1
Reputation: 7072
Since this question is quite old and AngularJS had had time to evolve since then, this can now be easily achieved using:
<li ng-repeat="record in records" ng-bind="record + ($last ? '' : ', ')"></li>
.
Note that I'm using ngBind
instead of interpolation {{ }}
as it's much more performant: ngBind
will only run when the passed value does actually change. The brackets {{ }}
, on the other hand, will be dirty checked and refreshed in every $digest, even if it's not necessary. Source: here, here and here.
angular
.module('myApp', [])
.controller('MyCtrl', ['$scope',
function($scope) {
$scope.records = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
}
]);
li {
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<ul>
<li ng-repeat="record in records" ng-bind="record + ($last ? '' : ', ')"></li>
</ul>
</div>
On a final note, all of the solutions here work and are valid to this day. I'm really found to those which involve CSS as this is more of a presentation issue.
Upvotes: 3
Reputation: 26784
If you are using ng-show to limit the values, the {{$last ? '' : ', '}}
won`t work since it will still take into consideration all the values.Example
<div ng-repeat="x in records" ng-show="x.email == 1">{{x}}{{$last ? '' : ', '}}</div>
var myApp = angular.module("myApp", []);
myApp.controller("myCtrl", function($scope) {
$scope.records = [
{"email": "1"},
{"email": "1"},
{"email": "2"},
{"email": "3"}
]
});
Results in adding a comma after the "last" value,since with ng-show it still takes into consideration all 4 values
{"email":"1"},
{"email":"1"},
One solution is to add a filter directly into ng-repeat
<div ng-repeat="x in records | filter: { email : '1' } ">{{x}}{{$last ? '' : ', '}}</div>
Results
{"email":"1"},
{"email":"1"}
Upvotes: 0
Reputation: 215
I think it's better to use ng-if
. ng-show
creates an element in the dom
and sets it's display:none
. The more dom
elements you have the more resource hungry your app becomes, and on devices with lower resources the less dom
elements the better.
TBH <span ng-if="!$last">, </span>
seems like a great way to do it. It's simple.
Upvotes: 5
Reputation: 421
.list-comma::before {
content: ',';
}
.list-comma:first-child::before {
content: '';
}
<span class="list-comma" ng-repeat="destination in destinations">
{{destination.name}}
</span>
Upvotes: 42
Reputation: 2174
You can use CSS to fix it too
<div class="some-container">
[ <span ng-repeat="something in somethings">{{something}}<span class="list-comma">, </span></span> ]
</div>
.some-container span:last-child .list-comma{
display: none;
}
But Andy Joslin's answer is best
Edit: I changed my mind I had to do this recently and I ended up going with a join filter.
Upvotes: 10
Reputation: 43023
You could do it this way:
<b ng-repeat="email in friend.email">{{email}}{{$last ? '' : ', '}}</b>
..But I like Philipp's answer :-)
Upvotes: 342
Reputation: 1527
Also:
angular.module('App.filters', [])
.filter('joinBy', function () {
return function (input,delimiter) {
return (input || []).join(delimiter || ',');
};
});
And in template:
{{ itemsArray | joinBy:',' }}
Upvotes: 101
Reputation: 20961
Just use Javascript's built-in join(separator)
function for arrays:
<li ng-repeat="friend in friends">
<b>{{friend.email.join(', ')}}</b>...
</li>
Upvotes: 233