mika-el
11/25/2018 - 8:07 PM

Effects Examples

One input, one output

@Effect()
public firstAction$: Observable<Action> = this.actions$.pipe(
  ofType( 'FIRST_ACTION' ),
  mapTo( new SecondAction() )
);

This effect says:

  • Watch the Action Stream for any time FirstAction happens
  • Dispatch a new SecondAction into the Action Stream

Two inputs, one output

@Effect()
public dashboardLoadRequired$: Observable<Action> = 
  this.actions$.pipe(
    ofType( 'SIGN_IN_SUCCESS', 'OPEN_DASHBOARD'),
    mapTo( new LoadDashboardData() )
  );

This effect says:

  • Watch the stream for a SignInSuccess or an OpenDashboard
  • Dispatch a new LoadDashboardData action

One input, two outputs

@Effect()
public signInSuccess$: Observable<Action> = this.actions$.pipe(
  ofType( 'SIGN_IN_SUCCESS' ),
  concatMapTo([
    new LoadDashboardData(),
    new LoadChatHistory()
  ])
);

This effect says:

  • Watch the stream for a SignInSuccess action
  • Dispatch a LoadDashboardData action then a LoadChatHistory action

Two inputs, one output

Another common effect you might write is when multiple action types trigger the same result. The ofType operator allows for multiple types.

@Effect()
public dashboardLoadRequired$: Observable<Action> = 
  this.actions$.pipe(
    ofType( 'SIGN_IN_SUCCESS', 'OPEN_DASHBOARD'),
    mapTo( new LoadDashboardData() )
  );

This effect says:

  • Watch the stream for a SignInSuccess or an OpenDashboard
  • Dispatch a new LoadDashboardData action

One input, two outputs

@Effect()
public signInSuccess$: Observable<Action> = this.actions$.pipe(
  ofType( 'SIGN_IN_SUCCESS' ),
  concatMapTo([
    new LoadDashboardData(),
    new LoadChatHistory()
  ])
);

This effect says:

  • Watch the stream for a SignInSuccess action
  • Dispatch a LoadDashboardData action then a LoadChatHistory action

One input, no outputs

For this use-case, add {dispatch: false} to the effect decorator.

@Effect({dispatch: false})
public signInSuccess$: Observable<Action> = this.actions$.pipe(
  ofType( 'SIGN_IN_SUCCESS' ),
  tap( () => this.router.navigate(['dashboard']) )
);

This effect says:

  • Watch the stream for a SignInSuccess action
  • Navigate to the dashboard
  • Do not dispatch any further actions

Passing input payload to output

The above examples have used the operators mapTo and concatMapTo. These operators map to static values. Sometimes you want to map to dynamic values, such as using a value passed in via an action’s payload property. For dynamic values, use the matching operators map or concatMap which expect a function rather than a static value.

@Effect()
public signInSuccess$: Observable<Action> = this.actions$.pipe(
  ofType( 'SIGN_IN_SUCCESS' ),
  map( action => action.payload ),
  concatMap( payload => [
    new LoadDashboardData( payload.companyId ),
    new LoadChatData( payload.userId )
  ])
);

This effect says:

  • Watch the stream for a SignInSuccess action
  • Get the payload from the SignInSuccess action
  • Dispatch LoadDashboardData with the user’s companyId
  • Dispatch LoadChatData with the user’s userId