889

I have a simple ngFor loop which also keeps track of the current index. I want to store that index value in an attribute so I can print it. But I can't figure out how this works.

I basically have this:

<ul *ngFor="#item of items; #i = index" data-index="#i">
    <li>{{item}}</li>
</ul>

I want to store the value of #i in the attribute data-index. I tried several methods but none of them worked.

I have a demo here: http://plnkr.co/edit/EXpOKAEIFlI9QwuRcZqp?p=preview

How can I store the index value in the data-index attribute?

Wesley Coetzee
  • 4,768
  • 3
  • 27
  • 45
Vivendi
  • 20,047
  • 25
  • 121
  • 196
  • Just a note - with the `*ngFor` on the `UL` as in this question, this would repeat the `UL` for each item, not the `LI` – LocalPCGuy Apr 20 '23 at 16:11

10 Answers10

1507

I would use this syntax to set the index value into an attribute of the HTML element:

Angular >= 2

You have to use let to declare the value rather than #.

<ul>
    <li *ngFor="let item of items; let i = index" [attr.data-index]="i">
        {{item}}
    </li>
</ul>

Angular = 1

<ul>
    <li *ngFor="#item of items; #i = index" [attr.data-index]="i">
        {{item}}
    </li>
</ul>

Here is the updated plunkr: http://plnkr.co/edit/LiCeyKGUapS5JKkRWnUJ?p=preview.

tobias47n9e
  • 2,233
  • 3
  • 28
  • 54
Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
  • Just for curiosity, why `[attr['data-index']]=i ` would not work, where as it evaluate as same – Pankaj Parkar Feb 15 '16 at 09:50
  • 5
    In fact, the `attr.` is a syntax to tell Angular2 to set the value of the expression to the attribute name. It's not just like evaluating JSON, I guess ;-) See this link: https://angular.io/docs/ts/latest/guide/template-syntax.html – Thierry Templier Feb 15 '16 at 09:54
  • 1
    Thanks, that does the trick. Also, I meant to put the `ngFor` on the `li` instead of the `ul`. – Vivendi Feb 15 '16 at 10:10
  • 1
    I rolled back the recent edit in order to have both the original answer and the new updated code value. I was searching for some early beta stuff and saw that this answer was modified, so it no longer applied to the beta version of angular 2. – ps2goat Nov 17 '16 at 18:58
  • 4
    UPDATE: 08/2017
    – Maxi Aug 28 '17 at 22:21
  • 10
    as of Oct 17, 2018 Angular 6 is using *ngFor="let item of items; index as i" See Leo's answer below. – Gel Oct 18 '18 at 02:33
  • 1
    Angular 1.x (known as AngularJS as opposed to Angular) doesn't use `*nfFor` structural directive at all. On the old version you would `ng-repeat="item in items"` and then access provided variables within the template as `$index, $even, $odd...` [See the docs yourself.](https://docs.angularjs.org/api/ng/directive/ngRepeat) – Frozenfrank Aug 16 '19 at 06:43
484

In Angular 5/6/7/8:

<ul>
  <li *ngFor="let item of items; index as i">
    {{i+1}} {{item}}
  </li>
</ul>

In older versions

<ul *ngFor="let item of items; let i = index">
  <li>{{i+1}} {{item}}</li>
</ul>

Angular.io ▸ API ▸ NgForOf

Unit test examples

Another interesting example

Jeffrey Nicholson Carré
  • 2,950
  • 1
  • 26
  • 44
Leo
  • 10,407
  • 3
  • 45
  • 62
  • 3
    `index as i` works great, thank you. But isn't the `*ngFor` meant to go on the element to be repeated (e.g. the `
  • ` in this case)? The code you suggested creates multiple `
      `s rathers than multiple `
    • `s.
  • – Liran H Apr 08 '19 at 11:54
  • 1
    `index as i` is more elegant than `let i = index` – David Feb 04 '20 at 11:53