Skip to content

Instantly share code, notes, and snippets.

@bertrandg
Last active October 3, 2022 02:22
Show Gist options
  • Save bertrandg/7efbc924d60164d05daaa7d0b4f89267 to your computer and use it in GitHub Desktop.
Save bertrandg/7efbc924d60164d05daaa7d0b4f89267 to your computer and use it in GitHub Desktop.
ngrx/effects advance example
// Nothing changed here, works as previously.
@Effect() actionX$ = this.updates$
.ofType('ACTION_X')
.map(toPayload)
.switchMap(payload => this.api.callApiX(payload)
.map(data => ({type: 'ACTION_X_SUCCESS', payload: data}))
.catch(err => Observable.of({type: 'ACTION_X_FAIL', payload: err}))
);
// Here is the magic.
@Effect() actionY$ = this.updates$
.ofType('ACTION_Y')
.map(toPayload)
// Retrieve part of the current state telling us if callApiX has been called already.
.withLatestFrom(this.store.select(state => state.someBoolean))
.switchMap(([payload, someBoolean]) => {
// Function calling callApiY() and acting accordingly.
const callHttpY = v => {
return this.api.callApiY(v)
.map(data => ({type: 'ACTION_Y_SUCCESS', payload: data}))
.catch(err => Observable.of({type: 'ACTION_Y_FAIL', payload: err}));
}
// If data from store indicates that callApiX() has already been called with success
// Then directly call callApiY().
if(someBoolean) {
return callHttpY(payload);
}
// Otherwise emit action triggering callApiX()
// Then wait for first response action (success or fail)
// And act accordingly.
return Observable.of({type: 'ACTION_X', payload})
.merge(
this.updates$
.ofType('ACTION_X_SUCCESS', 'ACTION_X_FAIL')
.first()
.switchMap(action => {
if(action.type === 'ACTION_X_FAIL') {
return Observable.of({type: 'ACTION_Y_FAIL', payload: 'Because ACTION_X failed.'});
}
return callHttpY(payload);
})
);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment