Search code examples
angularfor-loopngforangular17

How to refactor ngFor when element uses the iteration variable on the element?


I have this

<div
    *ngFor="let dt of totals"
    [ngClass]="{ up: dt.isUp }"
>
    <span> {{ dt }}</span>
</div>

and I want to refactor to angular v17 syntax

@for (dt of totals; track $index) {
    <span>{{ dt }}</span>
}

How do I refactor the [ngClass] on the <div>?

I tried this but obviously It doesn't work because the variable dt is not yet defined inthe <div>

<div [ngClass]="{ up: dt.isUp }">
    @for (dt of totals; track $index) {
        <span>{{ dt }}</span>
    }
</div>

I could try this but I don't want an extra ng-container on every element:

<div>
    @for (dt of totals; track $index) {
        <ng-container [ngClass]="{ up: dt.isUp }">
            <span>{{ dt }}</span>
        </ng-container>
    }
 </div>

What's the official way to do this?

edit: Thanks for the help, I got the resolution I needed. The question is silly because I forgot that the *ngFor repeats the element it is in and its children. I forgot that and thought it was only repeating its children. That is basic pre-v17 angular. I'll leave this question in case this catches anyone else.


Solution

  • In your example you are creating multiple divs, by using the *ngFor so the equivalent of the same will be the below code.

    The line where you place the *ngFor get repeated.

    @for (dt of totals; track $index) {
        <div [ngClass]="{ up: dt.isUp }" >
            <span> {{ dt }}</span>
        </div>
    }
    

    If you do not want the div tag, then you can add the [ngClass] to the span, the ngClass must be attached to an HTML element. Since the class is present in html, we cannot use ng-container because there is no tag present in the HTML during rendering!

    @for (dt of totals; track $index) {
        <span [ngClass]="{ up: dt.isUp }"> {{ dt }}</span>
    }