await / async (props) of Observables | Promises etc
See original GitHub issueWhich @angular/* package(s) are relevant/related to the feature request?
No response
Description
Angular allows us to use async pipe but when using multiple streams there isn’t really a great way to ngIf them.
Imagine the scenario I have observables a$ and b$ and I want to wait for both of them. Of course I could make another observable in my TS file and combineLatest them but this means I would need to that for every scenario in my HTML and it dosent make much sence to combine them in the TS if all I want is to display a loading animation.
I went trough a few possible solutions and think this could be a standard Angular feature. I’m open for discussions and suggestions but as far as the testing / working of the idea goes it seems to work fine.
Proposed solution
I propose we have a similar async pipe but it would work only for keys of observables, this way you can keep your HTML clean and robust. The following code will recreate an object based on the current one but with the catch that it will map all observables to another object with the returned values from the stream.
<ng-container *ngIf="{ myData$, selectedItems$, myPromise$ } | await as props; else loading">
<my-multi-selector
[selectedItems]="props.selectedItems$.value"
[data]="props.myData$.value"></my-multi-selector>
</ng-container>
<ng-template #loading>
<div>Loading...</div>
</ng-template>
Alternatives considered
Regarding the implementation I made a sample app which I tested and it seems to work fine. There is a catch to my code and that is that I catch the object and compare references - this is completely fine if you use the code as above written but there is an issue if you e.g. create your object in TS and then dynamically change the keys (adding / removing keys will cause issues without creating a new instance of the object itself).
This can be avoided by removing the comparison of the references of the new and old object but since this isn’t a pure pipe I considered the performance impact and since this would be used only in HTML anyway I think this is the best possible solution - again I’m open for discussion.
Link of example: https://github.com/muhamedkarajic/angular-playground/blob/main/src/app/shared/pipes/await.pipe.ts
Issue Analytics
- State:
- Created a year ago
- Reactions:2
- Comments:10 (3 by maintainers)
Top GitHub Comments
Sorry but I think this is really really not a duplicate.
How do you expect that to work with async which returns null instantly and then awaits the observbale to start passing data.
I have looked into the async pipe and its not extendable cause my syntax in HTML requires you to create an object {a$, b$, c$} the async pipe bahavior would return {a$: null, b$: null, c$: null} and you can’t just make it behave differently cause the type my ‘await’ pipe returns and the type whcih async pipe returns is completly different - unless you can somehow manage to make that in typescript or using the angular CLI.
A similar syntax could be used then, as with RxJS operators, i.e.,
*ngIf="{ myData$, selectedItems$, myPromise$ } | combineLatest as props; else loading"
. 😄