ElearningWorld.org

For the online learning world

Elearning WorldTechnical

Angular NGRX synchronous subscriptions?

Sometimes it’s necessary to pull things out of the store in a synchronous fashion — i.e. to avoid race conditions.

In my early days of NGRX I did this using nested subscriptions and quickly discovered that it was an anti-pattern in the NGRX world.

I’m not going to paste in a huge amount of code to illustrate the wrong and right approach — let’s just assume we have a class with an NGRX _store property, a reducer called fromReducer, and the class properties socks, shoes and coats.

Doing it wrong (nested subscriptions):

this._store.select(fromReducer.getSocks) .filter(socks => !!socks)
.subscribe(socks => { this.socks = socks;
this._store.select(fromReducer.getShoes)
.filter(shoes => !!shoes)
.subscribe(shoes => { this.shoes = shoes;
this._store.select(fromReducer.getCoat)
.filter(coat => !!coat)
.subscribe(coat => { this.coat = coat;
this.dressed = this.coat && this.shoes && this.socks; }); }); });

Doing it right with switchMap:

this._store.select(fromReducer.getSocks) .filter(socks => !!socks) .switchMap(socks => {
// I need my socks BEFORE my shoes, so this can’t be
// asynchronous. this.socks = socks;

// Return an Observer which selects the next bit of data
// I need, which is my shoes. return this._store.select(fromReducer.getShoes); }) .filter(shoes => !!shoes) .switchMap(shoes => { this.shoes = shoes; return this._store.select(fromReducer.getCoat); }) .subscribe(coat => { this.coat = coat; // Here’s another bit that wouldn’t work well with async
// – I need to have the status of coat, shoes and socks
// before I can set the ‘dressed’ property this.dressed = this.coat && this.shoes && this.socks; });

UPDATE TO ARTICLE

A genius NGRX friend of mine has pointed out that an alternative method would be better (using .withLatestFrom) :

this._store.select(fromReducer.getSocks) .withLatestFrom(this._store.select(fromReducer.getShoes), this._store.select(fromReducer.getCoat)) .filter(([socks, shoes, coat]) => !!shoes && !!socks) .subscribe(([socks, shoes, coat]) => { this.coat = coat; this.shoes = shoes; this.socks = socks; this.dressed = this.coat && this.shoes && this.socks; }); Source: https://brudinie.medium.com/feed

blank
Follow me

blank

ElearningWorld Admin

Site administrator

Add a reply or comment...