0
votes

I want to write an effect which gets some data from store and dispatch actions based on some condition. I have my effect something like this

 onManageTab$ = createEffect(() =>
    this.actions$.pipe(
      ofType(TabsActions.manageTab),

      // The idea to go with switchMaps and forkjoins over withLatestFrom is
      // `withLatestFrom` fetches undefined state here (think store is not properly created at that point)

      switchMap(action =>
        forkJoin(
          of(action),
          this.store.select(TabSelectors.getAllTabsInfo).pipe(take(1))
        )
      ),
      switchMap( ([action, tabsInfo]) => { 

        if (someCond) {
          return [  TabsActions.addTab({  payload: {pageInfo: action.payload.pageInfo} })];
        }
        return [TabsActions.updateActiveTab({  payload: {pageID: existingTabID} })];

        // some workaround to make it work
        return of({
          type: '[Tab] Dummy action',
        });
      })
    )
  );

I was facing issue to get latest value from store using withLatestFrom so I managed to get it using switchMap and passed action and some tabInfo to another switchMap. Now I want to dispatch different action based on some condition. (Note: I created my reducer and actions with extra payload prop, I was handling it accordingly)

I get the following error if I remove return of dummy action ('[Tab] Dummy action')

Type 'Observable<{}>' is not assignable to type 'Observable<Action>'.
    Property 'type' is missing in type '{}' but required in type 'Action'.

Argument of type 
'([action, tabsInfo]: [{ payload: { pageInfo: PageInfo; }; } & TypedAction<"[Tab] Manage tab">, PageInfo[]]) => Observable<{ type: string; payload: { pageInfo: PageInfo; }; }> | Observable<{ type: string; payload: { ...; }; }>' 
is not assignable to parameter of type 
'(value: [{ payload: { pageInfo: PageInfo; }; } & TypedAction<"[Tab] Manage tab">, PageInfo[]], index: number) => ObservableInput<{ type: string; payload: { pageInfo: PageInfo; }; }>'.

I am understanding that it is throwing error because my payload in the actions is different. But is it not possible to dispatch actions with different payloads based on condition.

Why does it work if I have an action with no payload as return ?

Please let me know if you want to know the complete error trace to have more insight

Edit: Below is how I created actions

export const addTab = createAction(
  '[Tab] Add tab',
  props<{ payload: { pageInfo: PageInfo } }>()
);

export const updateActiveTab = createAction(
  '[Tab] Update active tab',
  props<{ payload: { pageID: string } }>()
);
1
Things to try: You're returning an array of a single action where you return TabsActions.addTab and TabsActions.updateActiveTab. Remove the square brackets so you return only an action. Show the code of your action creators as it's possible they're not being created in the correct manner. Re your final point, yes it is possible to return actions with different payloads so I suspect the problem lies elsewhere.wlf

1 Answers

0
votes

I found a workaround for my problem. I tried to write 2 effects, which either returns [Action] or EMPTY

 onManageTabCondTrue$ = createEffect(() =>
    this.actions$.pipe(
      ofType(TabsActions.manageTab),
      switchMap(action =>
        forkJoin(
          of(action),
          this.store.select(TabSelectors.getAllTabsInfo).pipe(take(1))
        )
      ),
      switchMap( ([action, tabsInfo]) => { 

        if (someCond) {
          return [  TabsActions.addTab({  payload: {pageInfo: action.payload.pageInfo} })];
        }
        return EMPTY;
      })
    )
  );

 onManageTabCondFalse$ = createEffect(() =>
    this.actions$.pipe(
      ofType(TabsActions.manageTab),
      switchMap(action =>
        forkJoin(
          of(action),
          this.store.select(TabSelectors.getAllTabsInfo).pipe(take(1))
        )
      ),
      switchMap( ([action, tabsInfo]) => { 

        if (!someCond) {
           return [TabsActions.updateActiveTab({  payload: {pageID: existingTabID} })];
        }
        return EMPTY;
      })
    )
  );

Note: The problem is I have to write a new effect for each new condition.