Search code examples
angularrxjsngrxngrx-effectsngrx-entity

pessimistic update using ngrx entity


i have my actions setup like this

    export const bankAccountUpdating = createAction(
  '[Create New Account Component] Account Updating',
  props<{ update: Update<BankAccount> }>()
);

export const bankAccountUpdated = createAction(
  '[Bank Manager Effect] Account Updated',
  props<{ update: Update<BankAccount> }>()
);

export const updateAccountError = createAction(
  '[Bank Manager Effect] Update Accounts Error'
);

and the reducers are setup like this

 export const initialBankAccountsState = adapter.getInitialState({
  allBankAccountsLoaded: false,
});

export const bankManagerReducer = createReducer(
  initialBankAccountsState,

  on(BankManagerActions.bankAccountUpdated, (state, action) =>
    adapter.updateOne(action.update, state)
  ),

note that adapter.updateOne needs object of type Update from ngrx entity.

i have an effect setup that triggers on Updating and once server's response is returned i am trying to call "updated" action

 updateAccount$ = createEffect(
() =>
  this.actions$.pipe(
    ofType(BankManagerActions.bankAccountUpdating),
    concatMap((action) =>
      this.bankManagerHttpService
        .updateAccount(action.update.id, action.update.changes)
        .pipe(
          catchError((err) => {
            console.log(err);
            this.store.dispatch(BankManagerActions.updateAccountError());
            return of();
          })
        )
    ),
    map((account) => BankManagerActions.bankAccountUpdated({ account }))) //<--PROBLEM
   // ,{ dispatch: false }  );

problem is here when i am trying to call BankManagerActions.bankAccountUpdated it needs object of type Update so that it can call "updateOne" on adapter (in reducers) but at this point i dont have hold of action. how can i call BankManagerActions.bankAccountUpdated with Update object ?


Solution

  • You should move your map operator inside updateAccount observable pipe:

    updateAccount$ = createEffect(() =>
      this.actions$.pipe(
        ofType(BankManagerActions.bankAccountUpdating),
        concatMap((action) =>
          this.bankManagerHttpService
            .updateAccount(action.update.id, action.update.changes)
            .pipe(
               map(account => BankManagerActions.bankAccountUpdated({update: {id: action.update.id, changes: account}})), // action here
               catchError((err) => {
                console.log(err);
    
                return of(BankManagerActions.updateAccountError());
              })
            )
        ),
    );
    

    I removed {dispatch: false} and store.dispatch as well.