# NgFor

```markup
<div *ngFor="let hero of heroes; let i=index; let odd=odd; trackBy: trackById" [class.odd]="odd">
  ({{i}}) {{hero.name}}
</div>

<ng-template ngFor let-hero [ngForOf]="heroes" let-i="index" let-odd="odd" [ngForTrackBy]="trackById">
  <div [class.odd]="odd">({{i}}) {{hero.name}}</div>
</ng-template>
```

* The **template** **input variables**&#x20;
  * A template input variable is a variable whose value you can reference within a single instance of the template.
* * in this example are `hero`, `i`, and `odd`.&#x20;
  * The parser translates let hero, let i, and let odd into variables named, `let-hero`, `let-i`, and `let-odd`.
* The **input properties**
  * The microsyntax parser takes of and trackBy, title-cases them (of -> Of, trackBy -> TrackBy), and prefixes them with the directive's attribute name (ngFor), yielding the names ngForOf and ngForTrackBy.&#x20;
  * That's how the directive learns that the **list** is heroes and the **track-by function** is trackById.
* The string assigned to `*ngFor` is **not** a template expression. It's a **microsyntax** — a little language of its own that Angular interprets.&#x20;
* \*ngFor with **index**
  * The **index** property of the NgForOf directive context returns the zero-based index of the item in each iteration.
  * ```markup
    <div *ngFor="let hero of heroes; let i=index">{{i + 1}} - {{hero.name}}</div>
    ```
* \*ngFor with **trackBy**
  * The NgForOf directive may perform poorly, especially with large lists. A small change to one item, an item removed, or an item added can trigger a cascade of DOM manipulations.
  * Angular can avoid this churn with trackBy. Add a method to the component that returns the value NgForOf should track. In this case, that value is the hero's id.
  * ```javascript
    trackById(index: number, hero: Hero): number { return hero.id; }
    ```

\[R] <https://angular.io/guide/structural-directives#microsyntax>
