Reputation: 1420
I recently started working on a new project and I have seen this twice now, am I crazy or will never work under any circumstance?
protected get reportView(): any {
let convertedView = null;
this.store
.pipe(select(fromStore.getTransferOrderConverted), rxjs.take(1))
.subscribe((convertedOrder) => (convertedView = convertedOrder));
return convertedView;
}
Upvotes: 2
Views: 3260
Reputation: 1
Rxjs take(1), first() operator should work absolutely fine
These 2 operators takes the latest value from store selector or BehaviourSubject in synchronous way.
Upvotes: 0
Reputation: 8022
am I crazy or will never work under any circumstance?
Q) Are you crazy?
A) Yes. Absolutely. That looks bonkers!
Q) Will this never work under any circumstance?
A) Oh, there are times this will work. Some observables are synchronous.
For example, this will always log a 2
, so this works as expected.
let convertedView = null;
of(1).pipe(
map(v => v + 1)
).subscribe(convertedOrder => convertedView = convertedOrder);
console.log(convertedView);
That's because of(1)
is a synchronous observable.
This, however, will never work
let convertedView = null;
of(1).pipe(
delay(0),
map(v => v + 1)
).subscribe(convertedOrder => convertedView = convertedOrder);
console.log(convertedView);
This will print null
. Even though delay(0)
conceptually takes no time, it still uses JSs event loop and therefore doesn't get executed until the current code completes.
I think it's best practise to assume all observables
are asynchronous. Any code that assume otherwise is likely to be brittle.
Upvotes: 3
Reputation: 121
Convert a stream to synchronous isn't a good ideal.
However, you can use method toPromise
of a subject (subscription) for convert it to a promise and await for resolve.
Upvotes: 0
Reputation: 1011
Your store.subscribe
is asynchronous and the rest of your code is not.
You can resolve it with a Promise like the example below.
protected get reportView(): Promise < any > {
return new Promise((resolve, reject) => {
this.store
.pipe(select(fromStore.getTransferOrderConverted), rxjs.take(1))
.subscribe((convertedOrder) => resolve(convertedOrder));
});
}
reportView.then(convertedOrder => {
// do your stuff
});
Also you can get the convertedOrder with Async/Await. But remember, the parent function must be async
.
const convertedOrder = await reportView();
Upvotes: 1