6
votes

I have this effect for logout confirmation under the condition of a dialog response, but am getting the following errors:

ERROR Error: Effect "AuthEffects.logoutConfirmation$" dispatched an invalid action: undefined

and

ERROR TypeError: Actions must be objects

heres the effect:

@Effect()
logoutConfirmation$ = this.actions$
    .ofType<Logout>(AuthActionTypes.Logout)
    .pipe(
      map(action => {
        if (action.confirmationDialog) {
          this.dialogService
            .open(LogoutPromptComponent)
            .afterClosed()
            .pipe(
              map(confirmed => {
                if (confirmed) {
                  return new LogoutConfirmed();
                } else {
                  return new LogoutCancelled();
                }
              })
            );
        } else {
          return new LogoutConfirmed();
        }
      })
    );

it works when confirmation dialog is activated, I guess it's something wrong with the map of the dialog's response, have been trying to understand it but couldn't fin a way. Any one has a clue on this?

3
Is it a runtime or compiletime error ? - korteee
no, it's when the action is dispatched. - dazzed
Try adding return this.dialogService //etc... - korteee
got Effect "AuthEffects.logoutConfirmation$" dispatched an invalid action: [object Object] and Actions must have a type property - dazzed
Declare the explicit type of logoutConfirmation$ as logoutConfirmation$:Observable<Action> and see what happens ;) - Jota.Toledo

3 Answers

10
votes

Your outer map should be a mergeMap, as you are mapping the action to a new stream (in case that the condition is true).

You can fix this as follows:

import { of } from 'rxjs';
import {map, mergeMap } from 'rxjs/operators';

@Effect()
logoutConfirmation$: Observable<Action> = this.actions$
    .ofType<Logout>(AuthActionTypes.Logout)
    .pipe(
      mergeMap(action => {
        if (action.confirmationDialog) {
          return this.dialogService
            .open(LogoutPromptComponent)
            .afterClosed()
            .pipe(
              map(confirmed => confirmed ? new LogoutConfirmed():new LogoutCancelled())
            );
        } else {
          return of(new LogoutConfirmed());
        }
      })
    );

As a side note, always declare the explicit type of your effects in order to get errors at compile instead of run time.

6
votes

In my case I wasn't dispatching anything so putting dispatch:false inside of @effect() fixed my issue.

@Effect({dispatch: false})

0
votes

this happens when you don't call this action type in your reducer you need to put something like this in your reducer with same action type you are using in your effect :

case AuthActionTypes.Logout:
            return {
                ...state
            };

@Stephen Romero answer will work but it will ignore dispatching new values