HOST-X
HOST-X

Reputation: 463

How using Angular 14 trackBy Function with strict-mode: true?

I have the problem to use trackBy in angular 14 with strict-mode: true,

This is the code (which works like charme in strict-mode: false)

app.component.html:

<div *ngFor="let item of items; index as i; trackBy: trackByFn">
  {{ i + 1 }} {{item.name}}
</div>


<br>

<button (click)="addSomething()">Load Data</button>

app.components.ts

import { Component } from '@angular/core';

interface DemoArray {
  id: number;
  name: string;
}

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  title = 'angular-sandbox';

  public items: DemoArray[] = [
    { id: 0, name: 'Apfel' },
    { id: 1, name: 'Mango' },
    { id: 2, name: 'Birne' },
  ];

  public addSomething(): void {
    this.items = [
      { id: 0, name: 'Apfel' },
      { id: 1, name: 'Mango' },
      { id: 2, name: 'Birne' },
      { id: 3, name: 'Kiwi' },
      { id: 4, name: 'Mandarine' },
      { id: 5, name: 'Banane' },
    ];
  }

  trackByFn(item) {
    return item.id;
  }
}

When using strict-mode:true and changing the trackByFn to:

  trackByFn(item: { id: any }) {
    return item.id;
  }

VSCode says:

Type '(item: { id: any; }) => any' is not assignable to type 'TrackByFunction'.ngtsc(2322) app.component.ts(8, 44): Error occurs in the template of component AppComponent.

Upvotes: 5

Views: 2325

Answers (3)

mario89
mario89

Reputation: 143

In case when you don't want use Type any, your second parameter need to match Type of iterable element of ngFor.

Some example if you iterate over FormGroup:

<div *ngFor=let formGroup of formArray.controls; trackBy: trackById>
    <!-- enter code here -->
</div>
public formArray: FormArray;

public trackById(_index: number, item: FormGroup | AbstractControl) {
    return item.value.id;
}

Angular Documentation

Upvotes: 0

HOST-X
HOST-X

Reputation: 463

Changing the Function to:

  trackByFn(index: any, item: { id: any }) {
    return item ? item.id : undefined;
  }

does the trick for me!

Upvotes: 1

Pankaj Parkar
Pankaj Parkar

Reputation: 136194

Strict mode in Angular enables below things

  • Enables strict mode in TypeScript
  • Strict angular compiler strictTemplates, strictInjectionParameters, and strictInputAccessModifiers
  • Reduced bundle size budget

Because strictTemplates types on templates are strictly checking its types, like how it does in typescript.

Now in this case, trackBy we are passing TrackByFunction. Currently written trackByFn does not follow the type TrackByFunction.

interface TrackByFunction<T> {
  <U extends T>(index: number, item: T & U): any
}

So the trackByFn function should follow the TrackByFunction interface signature.

trackByFn(index: number, item: { id: any }) {
   return item.id;
}

Upvotes: 9

Related Questions