8

I have a pretty basic scenario (somewhat new to angular). I am trying to convert JSON:

[
    {'name': 'Nick'},
    {'name': 'David'},
    {'name': 'John'},
]

To:

<p>Nick,David,John</p>

But I can not figure out how to generate a single "p." How do you call ng-repeat inside of the <p>

<p ng-repeat="item in menuItems">{{item.name}}</p>
Nix
  • 57,072
  • 29
  • 149
  • 198

7 Answers7

16

One thing that would be helpful is creating a "map" filter, like so:

myModule.filter('map', function() {
  return function(input, propName) {
    return input.map(function(item) {
      return item[propName];
    });
  };
});

That's the simple case of mapping to a named property, you could make it more fancy and understand dot notation, etc. Now with this, in your view you can do:

<p>
  {{(menuItems | map:'name').join(',')}}
</p>

Because the map filter returns an Array, which has a built-in join method already in Javascript.

jpsimons
  • 27,382
  • 3
  • 35
  • 45
3

You cannot do this. Instead, use a map and join. For example:

<p>{{names}}</p>

$scope.menuItems = [
  {'name': 'Nick'},
  {'name': 'David'},
  {'name': 'John'},
];
$scope.$watch('menuItems', function(menuItems) { 
    $scope.names = menuItems.map(function(item) { return item.name }).join(',');
});

This will $watch the menuItems and update the names property of the $scope whenever menuItems changes.

Matt York
  • 15,981
  • 7
  • 47
  • 51
  • I dont know if its that simple. I have a "MenuController" that that leverages a service, which calls json and returns it. Right now its reused, and in one case i want to flatten it. – Nix May 21 '13 at 15:27
  • Okay, but I don't see the problem. The MenuController can call the service and assign the result to `$scope.menuItems`. The `$watch` will be triggered when `menuItems` changes. The `$watch` function doesn't change the value of `menuItems`, so `menuItems` can be reused as much as you like. – Matt York May 21 '13 at 15:29
  • I guess you are always creating a csv version and adding it to scope. So this would work. – Nix May 21 '13 at 15:38
0

I'm not sure its possible... How to use ng-repeat without an html element

But you can always do:

<p>
    <span ng-repeat="item in menuItems">{{item.name}},</span>
</p>
Community
  • 1
  • 1
Nick
  • 6,366
  • 5
  • 43
  • 62
0

Here's another approach that's more maintainable using Filters:

app.filter('commaSeparated', function () {
    return function(input, property) {
        var csv = '';
        for (var i = 0; i < input.length; i++) {
            csv += input[i][property];
            if (i < input.length - 1) {
                csv += ',';
            }
        }
        return csv;
    };
});

Obviously, you can replace the literal array with your $scope.menuItems...

<p>
    {{ [ {'name': 'Nick'}, {'name': 'David'}, {'name': 'John'} ] | commaSeparated:'name' }}
</p>
Nick
  • 6,366
  • 5
  • 43
  • 62
0

I like the idea of a map filter. That's cool. For less code try this answer. Skip the name property and the ng-repeat and use the join() function:

<p>{{people.join(', ')}}</p>

Unfortunately, this does not work:

<p>{{people.map(function(item){return item.name;}).join(', ')}}</p>
Community
  • 1
  • 1
Michael Cole
  • 15,473
  • 7
  • 79
  • 96
0

If you are open to use <span> instead of<p>, then following array of objects,

[
      { "name": "John" },
      { "name": "David" },
      { "name": "Gopal" },
      { "name": "Anil" },
      { "name": "Gurjeet" }
]

can be displayed as: John, David, Gopal, Anil and Gurjeet

with this code snippet:

<span ng-repeat="admin in data">{{$first ? '' : $last ? ' and ' : ', '}}{{admin.name}}</span>

Got this solution from: AngularJS ng-repeat, comma separated with 'and' before the last item

Thanks!

Community
  • 1
  • 1
harman052
  • 919
  • 3
  • 9
  • 14
0

You could also accomplish that like this:

<p>    
   <span ng-repeat="(item,name) in menuItems">{{name}}{{$last ? '' : ', '}} </span>
</p>

I used this approach on a similar issue I had, I try to never mix javascript/jquery and angular. Got the solution from here: Using comma as list separator with AngularJS

Community
  • 1
  • 1