Search code examples
angularangular-signals

How to declare a variable in a template?


I have a signal defined as such:

export enum LoadingReason {
  indexingFiles,
}

export interface LoadingState {
  reason: LoadingReason;
  percent?: number;
}
isLoading: Signal<false | LoadingState>;

In the template, I'm tring to read the percent property, which generates a static error, because Typescript has no way to guarantee that the type of isLoading() is not false.

@if(isLoading() !== false && isLoading().percent === undefined){
  <mat-spinner diameter="30"></mat-spinner>
}

Usually, in the controller side, this would be fixed by defining a variable that holds the contents of the signal.

Example (that cannot be done in the template, but works in the controller):

const isLoading = this.isLoading();
if (isLoading !== false && isLoading.percent !== undefined) {
...
}

How can I handle this case with Angular's Signals?


Solution

  • Since Angular 18.1, you can declare a local template variable with @let like the following:

    @let loading = isLoading();
    @if (loading !== false && loading.percent === undefined) {
      <mat-spinner diameter="30" />
    }
    

    StackBlitz demo

    As of Angular v18.x, @let is in developer preview and may change before being advanced to stable