question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

await / async (props) of Observables | Promises etc

See original GitHub issue

Which @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:open
  • Created a year ago
  • Reactions:2
  • Comments:10 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
muhamedkarajiccommented, Aug 21, 2022

I believe that this issue is a duplicate of #15280 - while it suggest a different approach the underlying problem is the same: consuming observables in templates is not ideal and ergonomics of the async pipe could be improved.

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.

1reaction
mlc-mlapiscommented, Aug 6, 2022

A similar syntax could be used then, as with RxJS operators, i.e., *ngIf="{ myData$, selectedItems$, myPromise$ } | combineLatest as props; else loading". 😄

Read more comments on GitHub >

github_iconTop Results From Across the Web

RxJS Observable interop with Promises and Async-Await
RxJS Observable interop with Promises and Async-Await. Every now and then I'm asked a question about how to use async functions or promises...
Read more >
Promises & Async Await | Hands on React
Synchronous execution means the execution happens in a single series. A->B->C->D. If you are calling those routines, A will run, then finish, then...
Read more >
Callbacks/Promises/Observables/Async-Await - Wilson Yu
The whole idea behind Async/Await is to be able to write asynchronous code, synchronously. While callbacks, promises, and observables all give us different...
Read more >
JavaScript Promises vs. RxJS Observables | by Daniel Weibel
The await keyword can be put in front of an expression that evaluates to a promise. The await keyword pauses the execution of...
Read more >
await - JavaScript - MDN Web Docs
await is usually used to unwrap promises by passing a Promise as the expression . Using await pauses the execution of its surrounding...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found