Reputation: 25751
I have an effect that worked but I need to chain it with a service that is called in another action after the state gets updated in the first action via a reducer.
The effect is below:
@Effect()
uploadSpecChange$: Observable<Action> = this.actions$.pipe(
ofType(AppActions.WorkspaceActionTypes.UploadChange),
switchMap((x: any) => {
let f = new FileReader();
f.readAsText(x.payload);
return fromEvent(f, 'load');
}),
map((result: any) => {
const raw = (<FileReader>result.target).result as string;
const res = JSON.parse(raw);
// console.log(res);
return
new AppActions.UploadComplete(res),
new AppActions.PerformCalc()
})
);
I added the second action but am now getting an Observable error.
Upvotes: 1
Views: 516
Reputation: 20142
You can do like this using switchMap & of operator
@Effect()
dispatchMultiAction$: Observable<Action> = this.actions$.pipe(
ofType<SomeAction.Dispatch>(someActions.Dispatch),
switchMap(_ =>
of(
new someActions.InitData(),
new someActions.GetData(),
new someActions.LoadData()
)
)
);
Upvotes: 0
Reputation: 6821
With multiple actions return in an @Effect
,
you need to use concatMap
instead of map
concatMap((result: any) => {
const raw = (<FileReader>result.target).result as string;
const res = JSON.parse(raw);
return [
new AppActions.UploadComplete(res),
new AppActions.PerformCalc()
]
})
Upvotes: 0
Reputation: 998
So, if you want to dispatch more than one action from an effect you could return an array of actions and replace your map
with a mergeMap
:
@Effect()
uploadSpecChange$: Observable<Action> = this.actions$.pipe(
ofType(AppActions.WorkspaceActionTypes.UploadChange),
switchMap((x: any) => {
let f = new FileReader();
f.readAsText(x.payload);
return fromEvent(f, 'load');
}),
mergeMap((result: any) => {
const raw = (<FileReader>result.target).result as string;
const res = JSON.parse(raw);
// console.log(res);
return [
new AppActions.UploadComplete(res),
new AppActions.PerformCalc()
];
})
);
However, if you want the PerformCalc
action to be dispatched once the UploadComplete
action is done, you should dispatch PerformCalc
as a side effect of UploadComplete
:
@Effect()
uploadSpecChange$: Observable<Action> = this.actions$.pipe(
ofType(AppActions.WorkspaceActionTypes.UploadChange),
switchMap((x: any) => {
let f = new FileReader();
f.readAsText(x.payload);
return fromEvent(f, 'load');
}),
map((result: any) => {
const raw = (<FileReader>result.target).result as string;
const res = JSON.parse(raw);
// console.log(res);
return new AppActions.UploadComplete(res);
})
);
@Effect()
uploadComplete$: Observable<Action> = this.actions$.pipe(
ofType(AppActions.WorkspaceActionTypes.UploadComplete),
map(() => new AppActions.PerformCalc())
);
Upvotes: 1