Search code examples
typescriptngrxngrx-effectsdecoupling

Register ngRx effect on a "success" action? Or should this be decoupled with a service?


Currently I subscribe a ngRx effect on a "success" action (assuming my action is loadDataSuccess)?

createEffect(() => {
    return this.actions$.pipe(
        ofType(loadDataSuccess), ...

It somehow stings in my head, that this is bad practice. Is it better if I'd subscribe in a service on the selector for data (which will fire after the loadDataSuccess action) and then dispatch a new action loadAdditionalStuffAfterLoadingData ?

store.select(data).subscribe( 
    data => store.dispatch(loadAdditionalStuffAfterLoadingData(data)));

Solution

  • Both are valid, and serve their purposes.

    Personally, I would use the Success action to load the additional information in your case. Because that makes the intention more clear. It's also more dangerous to listen to the state to dispatch an action, because that action could potentially update the same slice of the state, resulting in an infinite loop.

    I would like to also mention, that if you're listening to the selector to fetch data, that that could also be an effect, https://timdeschryver.dev/blog/start-using-ngrx-effects-for-this/#using-rxjs-observables.

    changed$ = createEffect(() => {
      return store.select(data).pipe(
        map(() => loadAdditionalStuffAfterLoadingData(data))
    })