Reputation: 909
Hi I want dispatch my new action "LoadConfig" in "loadFullService$" effect.
How to do ?
@Effect()
loadFullService$: Observable<Action> = this.actions$
.ofType<servicesActions.LoadFullService>(servicesActions.LOAD_FULL_SERVICE)
.switchMap(action => {
return this.apiService
.loadFullService(action.payload)
.map((service: Service) => new servicesActions.LoadFullServiceSuccess(service))
.catch(error => of(new servicesActions.LoadFailureAction(error)));
})
;
@Effect()
loadConfig$: Observable<Action> = this.actions$
.ofType<servicesActions.LoadConfig>(servicesActions.LOAD_CONFIG)
.switchMap(action => {
console.log("action config", action);
return this.apiService
.loadConfig(action.id, action.name)
.map((config: Configuration) => new servicesActions.LoadConfigSuccess(config))
.catch(error => of(new servicesActions.LoadConfigFailure(error)));
});
Upvotes: 0
Views: 2087
Reputation: 12372
Effects aren't functions that take one element. They are stream transformations, and you can use all the power of RxJS here. For example, to get what you asked for in the title:
@Effect()
loadConfig$: Observable<Action> = this.actions$
.ofType<servicesActions.LoadConfig>(servicesActions.LOAD_CONFIG)
.switchMap(action => Observable.of(
new OtherAction(),
new OtherAction2(),
);
Note: this is quite similar to 3rd version in the André's answer.
Upvotes: 0
Reputation: 5944
Import the Store service in the constructor.
constructor(
private store: Store<StoreType>,
)
Then inside the action call this.store.dispatch(newAction)
, with a do
operator (usual), anywhere after the ofType()
.
@Effect()
loadFullService$: Observable<Action> = this.actions$
.ofType<servicesActions.LoadFullService>(servicesActions.LOAD_FULL_SERVICE)
.do(action => {
this.store.dispatch(new servicesActions.LoadConfig(action.payload.id, action.payload.name))
})
.switchMap(action => {
return this.apiService
.loadFullService(action.payload)
.map((service: Service) => new servicesActions.LoadFullServiceSuccess(service))
.catch(error => of(new servicesActions.LoadFailureAction(error)));
});
Another general approach, which I used to like, is creating a new observable:
@Effect()
loadFullService$: Observable<Action> = this.actions$
.ofType<servicesActions.LoadFullService>(servicesActions.LOAD_FULL_SERVICE)
.switchMap(action => {
return this.apiService
.loadFullService(action.payload)
.mergeMap((service: Service) => {
return new Observable(observer => {
const successAction = new servicesActions.LoadFullServiceSuccess(service));
const newAction = new servicesActions.LoadConfig(action.id, successAction.name));
observer.next(successAction);
observer.next(newAction);
observer.complete();
});
})
.catch(error => of(new servicesActions.LoadFailureAction(error)));
});
The downside is that it adds more churn and following the code gets a bit harder sometimes.
Finally, a third approach:
@Effect()
loadFullService$: Observable<Action> = this.actions$
.ofType<servicesActions.LoadFullService>(servicesActions.LOAD_FULL_SERVICE)
.switchMap(action => {
return this.apiService
.loadFullService(action.payload)
.mergeMap((service: Service) => {
const successAction = new servicesActions.LoadFullServiceSuccess(service));
const newAction = new servicesActions.LoadConfig(action.id, successAction.name));
return Observable.from([successAction, newAction]);
})
.catch(error => of(new servicesActions.LoadFailureAction(error)));
});
Upvotes: 1