Barruzi
Barruzi

Reputation: 323

ngrx Effects: Dispatch Empty Action

How do I get my ngrx/store effect to dispatch an empty action? I'm running Angular 6/rxjs 6:

  @Effect()
  testEffect$ = this.actions$.ofType(FIRST_ACTION).pipe(
    map((x) => {
       if (x === y) {
          return new SECOND_ACTION;
       } else {
          fire.some.effect;
          return EMPTY;
       }
    })
  );

At the moment, I'm getting two errors: Effect "testEffect$" dispatched an invalid action: [object Object] followed by TypeError: Actions must have a type property.

I found this answer, but it doesn't seem to work with ng/rxjs 6. So far, I've tried the following (none work):

EMPTY, Observable.empty(), Observable.of() and Observable.of([]), { type: 'EMPTY_ACTION' }

Any help would be appreciated! I know I can use { dispatch: false }, but the actual effect has about five outcomes and only one of them doesn't use an action, so I'd rather have that last one return something as well.

Upvotes: 6

Views: 10018

Answers (3)

itay oded
itay oded

Reputation: 1040

you could just use filter

@Effect()
testEffect$ = this.actions$.ofType(FIRST_ACTION).pipe(
  filter(x => x === y),
  map( x => new SECOND_ACTION)
)

and if you still need the other case you can write another effect with dispatch: false

Upvotes: 3

Anton Dosov
Anton Dosov

Reputation: 346

Here is a possible solution:

@Effect()
  testEffect$ = this.actions$.ofType(FIRST_ACTION).pipe(
    tap((x) => { // do some side effect here
        if (x !== y ) {
            fire.some.effect;
        }
    }),
    filter((x) => x === y), // proceed only if condition is true
    map((x) => {
       return new SECOND_ACTION; // then return the needed action
    })
  );

Upvotes: 17

Thierry Falvo
Thierry Falvo

Reputation: 6290

This works for me (ng6) :

@Effect()
boardOpened$ = this.actions$
  .ofType<BoardActions.Open>(BoardActions.OPEN)
  .pipe(
    withLatestFrom(this.store.select(BoardSelectors.getState)),
    map(([action, state]: [Action, BoardReducer.State]) => {
      return !BoardReducer.isLoaded(state)
        ? new BoardActions.Load()
        : EMPTY;
    })
  );

or

@Effect()
boardOpened$ = this.actions$
  .ofType<BoardActions.Open>(BoardActions.OPEN)
  .pipe(
    withLatestFrom(this.store.select(BoardSelectors.getState)),
    switchMap(([action, state]: [Action, BoardReducer.State]) => {
      return !BoardReducer.isLoaded(state)
        ? of(new BoardActions.Load())
        : EMPTY;
    })
  );

Upvotes: 0

Related Questions