skip to Main Content

I have a setup in my Angular project where I need to conditionally render a component based on nested properties of an object. Here’s a simplified version of the scenario:

projectSignal is a Signal<Project | undefined> where Project can contain an array of Task objects.
Each Task object can contain a Permission object.

I’m using Angular’s template syntax to conditionally check for the existence of these nested properties before rendering a component. Here’s the code snippet I have:

TS: projectSignal: Signal<Project | undefined> = toSignal(this.store.select(selectActiveProject));

and the corresponding HTML:

  @if(project.tasks[0]; as task){
    @if(task.permission; as permission){
      <app-permission [permissionsSelected]="permission"></app-permission>
    }
  }
}

While this works, the nested *ngIf directives feel cumbersome and not very elegant. Is there a cleaner or more efficient way to handle such nested optional checks in Angular templates and signals ?

Additional Information:

projectSignal is derived from a state management store using toSignal.
The presence of project, tasks, and permission is optional and should be checked before accessing their properties.
I’m looking for best practices or recommendations to simplify or improve this code. Any advice or suggestions would be greatly appreciated!

2

Answers


  1. We can also use computed to get the inner permission and directly use it on the if condition. Compute will run when the source signal changes.

    TS:

    projectSignal: Signal<Project | undefined> = toSignal(this.store.select(selectActiveProject));
    permission: Signal<Permission | undefined> = computed(() => this.projectSignal()?.tasks?.[0]?.permission);
    

    HTML:

    @if(permission(); as permission){
      <app-permission [permissionsSelected]="permission"></app-permission>
    }
    

    We can use Typescript’s type safe check ?. to perform the null checking on a single if condition and then show the component.

    @if(project?.tasks?.[0]?.permission; as permission){
      <app-permission [permissionsSelected]="permission"></app-permission>
    }
    
    Login or Signup to reply.
  2. Using @if aliases or the new @let template variable declaration have both the same downside of tackling with a solution with bundle and runtime impacts.

    Until the framework lands narrowing support in template (subscribe to this issue), I’d stick a the non-null assertion operator.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search