Search code examples
angularrxjsngrxngrx-effectsrxjs-pipeable-operators

Dispatch second action after first action completes from component in NGRX/RXJS


I am new to using NGRX/RXJS in my angular application, and I have a situation where I have to dispatch an action from my component, which fetches data from an API if the property is empty and updates Store_1 and set a property, and then dispatch another action which uses that data from Store_1 to perform some functions in Store_2 and update state after action 1 completes and fill in "pluralconfig". This is the code I came up with but I dont think/believe it's the most efficient way to do this, and If I'm using the operators correctly.

  if(isEmpty(definition.pluralconfig == null))
     {
         this.store$.dispatch(new FormDBAction(definition.formId));

         let id = definition.id;
         this.formLoadSubscription = this.store$.select(getOrderById(id))
         .filter(v => v.pluralconfig != null).subscribe(() =>{

            this.store$.select<TosModel>(getOrderById(id)).subscribe(updatedDefinition => {
              this.store$.dispatch(new OrderDetailAction(updatedDefinition));
            });             
         });
     }
     else{
      this.store$.dispatch(new OrderDetailAction(definition));
     }

Solution

  • All this logic should be in effects something like

    //Effects file
    @Effect()
    loadOrderDetail$: = this.actions$.pipe(
    ofType(LOAD_ORDER_DETAIL),
    flatMap(action => {
        return this.store$.select<TosModel>(getOrderById(action.id)).pipe(first());
    })
    map(definition => definition.pluralconfig ? new FormDBAction(definition.formId): new OrderDetailAction(definition)})
    )
    
    @Effect()
    formDb$: = this.actions$.pipe(
    ofType(FORM_DB_ACTION),
    switchMap(action => {
        ///call api and fire  new FormDbActionSuccess(response.definition) which reducer will store
    })
    
    @Effect()
    onSuccessOrderDetail$: = this.actions$.pipe(
    ofType(FORM_DB_ACTION_SUCESS),
    map(action => new OrderDetailAction(action.definition))
    
    //Component
    definition$ = this.store.select(getOrderById(id));
    store.dispatch( new LoadOrderDetail(id));
    

    Have a look of the ngrx example app in https://github.com/ngrx/platform/tree/master/projects/example-app Thats were I learn the most