Franck Freiburger
Franck Freiburger

Reputation: 28448

Using comma as list separator with AngularJS

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

Answers (9)

Durrahan
Durrahan

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

Cosmin Ababei
Cosmin Ababei

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

Mihai
Mihai

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

the7erm
the7erm

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

simbu
simbu

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

Chris Stephens
Chris Stephens

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

Andrew Joslin
Andrew Joslin

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

sanusart
sanusart

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

Philipp Reichart
Philipp Reichart

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

Related Questions