The Angular documentation suggests using the non-null assertion operator !
. An example of this would be:
<user-detail [user]="(user$ | async)!"></user-detail>
Using the non-null assertion operator indicates that you are confident a value will always be present, which overrides TypeScript's null-checking behavior.
However, this approach is not always appropriate. It's best used when you can guarantee a value from the start, such as when defining observables with of()
.
Another approach could be turn your component inputs into observables, or to accept null
values, but now we're making 'dumb' components smarter.
Here are some general guidelines I stick to with examples:
1. Non-null assertion
If you are certain there will be a value from the beginning, use the non-null assertion operator:
<user-detail [user]="(user$ | async)!"></user-detail>
This is appropriate when you know user$ will always emit a value, perhaps because it is initialized with a value immediately.
2. If / else
If you are waiting for a value, implement a loading state and render the component once the value is available:
<ng-container *ngIf="user$ | async as user; else loading">
<user-detail [user]="user"></user-detail>
</ng-container>
<ng-template #loading>
<p>Loading...</p>
</ng-template>
In this case, ngIf checks if user$ has emitted a value. If it hasn't, the loading template is displayed.
3. Fallback value
If you need to render the component even while waiting for a value, provide a fallback:
<user-detail [user]="(user$ | async) || defaultUser"></user-detail>
Here, defaultUser is used as a fallback value until user$ emits a value. This approach is useful when you want to ensure the component is always rendered, even if the actual data is not yet available.
By following these rules and using the appropriate examples, you can ensure that your application handles values and loading states more effectively.
boolean | null
, that looks not correct to solve your issue. What is the exact compiler error you get? – Cyndethis.store.select<Data[]>(data);
to get a typed result. What you at least should be able to do is:this.store.select(data) as Observable<Data[]>
– Cyndeboolean | null
, i think this is the issue here – Garvy