3

Looking through ng-repeats source, it doesn't look like theres any instance of it using for-of. Is there any custom directive that does this or some other way of achieving this loop in templates to make use of iterator functions?

Class with iterator

class Cache{

  constructor(items){
    this.cache = {
      "one" : 1,
      "two" : 2
    };
  };

  // custom iterator that turns our cache into an array
  // for use in "for...of" loops
  [Symbol.iterator](){
    var index = 0;
    // turn cache object into array of its values (underscore method)
    var data = _.values(this.cache);

    return {
      next: function(){
        if(index < data.length){
          return {
            value: data[index++],
            done: false
          };
        }else{
          return { done:true };
        }
      }
    };
  };

};

var myCache = new Cache();
// looping my cache in simple js would look like
for(let val of myCache){
  console.log(val);
}
// 1, 2

proposed angularjs ng-repeat directive

<ul>
  <li ng-repeat="item in myCache track by $index"></li>
</ul>

However that does not work as ng-repeat does not implement for...of. My question is: is there a way to get the ng-repeat directive to work nicely with iterators with minimal interface changes, or better yet, a custom directive identical to ng-repeat that is made for for...of loops?

anson
  • 4,156
  • 2
  • 22
  • 30
  • This may help you: http://stackoverflow.com/questions/11873570/angularjs-for-loop-with-numbers-ranges – Jordan Drenth May 08 '16 at 19:52
  • 1
    ng-repeat's syntax is `object in array` or `(key, value) in object`. what are you trying to achieve? – Muli Yulzary May 08 '16 at 19:52
  • updated with example – anson May 08 '16 at 20:20
  • Have to agree with MuliYulzary, if you are just trying to iterate an object you don't need to create a custom iterator becase a) `ngRepeat` can already iterate objects and b) The ES2016 feature [Object.entries](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries) provides this implementation already – CodingIntrigue May 09 '16 at 08:13
  • Its not about changing my implementation. I know that (of course) there are tons of other ways I could structure my code that will work with ng-repeat. My question is more "if I wanted to use an iterator function with angular templates, could I? Is there a custom directive (other than ng-repeat) that allows this?" – anson May 09 '16 at 08:26

1 Answers1

1

You could just use Array.from to convert your iterable source to an array, which ngRepeat will be able to iterate:

<ul>
  <li ng-repeat="item in Array.from(myCache) track by $index"></li>
</ul>

Ideally this would happen in your javascript directive/controller:

scope.myCache = Array.from(new Cache());

View:

<ul>
  <li ng-repeat="item in myCache track by $index"></li>
</ul>
CodingIntrigue
  • 75,930
  • 30
  • 170
  • 176
  • Thanks, something like this or similar might be the closest thing to what I'm looking for without writing a custom repeat directive. I was really hoping for a less intrusive interface but I understand ng-repeat simply doesnt implement it. – anson May 09 '16 at 08:32