Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access action props in @ngrx effect with ofType for multiple actions

I have 2 Actions and an Effect for these 2 actions using ofType operator as below:

export const myActions = {
  actionA: createAction(`actionA`, props<{ a: string }>()),
  actionB: createAction(`actionB`, props<{ b: number }>())
}

myEffect$ = createEffect(() =>
  this.actions$.pipe(
    ofType(myActions.actionA, myActions.actionB),
    mergeMap(action => {
      // How to convert action object to correct type and access action.a or action.b props?
      if (action.type == myActions.actionA) {
        console.log(action.a); // compile error
      } else if (action.type == myActions.actionB) {
        console.log(action.b); // compile error
      }
    })
  ), {dispatch: false}
);

How can I check and access props of actions (action.a and action.b) and with auto-completion from IDE?

like image 746
Xuan Avatar asked Feb 23 '20 11:02

Xuan


1 Answers

ofType takes as generic params type of action e.g. ofType<Action>(actionType) then merge map argument will be typed as Action without typing.

In your case action argument can be ActionA or ActionB as well, so you have to write ofType<ActionA | ActionB>(actionTypeA, actionTypeB), then action from mergeMap will be typed as Union of ActionA and ActionB. But in proper if's branches like (action.type == myActions.actionA) action will be only ActionA typed, because TS complier understand some of ifs statement.

BTW advice of @timdeschryver to split it into 2 effects is very good.

==============edited=================

If you're defining action by export const actionA = createAction('actionA', props<{ a: string }>()) you can declare type of ActionA by type ActionA = ReturnType<typeof actionA>;. ReturnType is generic added to TypeScript.

like image 126
Przemyslaw Jan Beigert Avatar answered Oct 21 '22 18:10

Przemyslaw Jan Beigert