Reputation: 301
When new SaveModelAction()
is called, the corresponding Effect gets stuck in an infinite loop.
This the effect:
@Effect() saveModelAction = this.action$.pipe(
ofType(SAVE_MODEL),
switchMap((action: any) => {
const storageMetaData: StorageData = action.payload;
return this.modelService.loadState()
.pipe(
switchMap((state: State) => {
const model: Model = AnalysisUtils.convertStateToModel(state, storageMetaData);
return this.modelService.saveModel(model)
.pipe(
map(() => new SavingModelCompleteAction),
catchError((error: Error) => this.createErrorObservableAndLog(error))
);
}),
catchError((error: Error) => this.createErrorObservableAndLog(error))
);
})
);
Additional info:
SaveModelAction
is only disptached once. this.modelService.loadState()
, take(1)
is used.this.modelService.saveModel(model)
does nothing except sending the model to the backend (and returning an observable.Can anyone point me in the right direction on where my issue is? Thanks!
Upvotes: 1
Views: 2994
Reputation: 43
I had the same issue, effect was stuck in an infinite loop and take(1) solved it for dispatching it only once.
The problem was that I had 2 actions which had the same type :(
This should work perfectly, so in case of infinite loop of effect or action, check the constants type :)
Good luck everyone!
Upvotes: 1
Reputation: 74
switchMap
has a different purpose.
As I can see, you just want to flatten Observables, so you should use flatMap
or mergeMap
instead of switchMap
.
More about these operators: https://www.learnrxjs.io/operators/transformation/switchmap.html
Try something like this:
@Effect() saveModelAction = this.action$.pipe(
ofType(SAVE_MODEL),
mergeMap((action: any) => {
const storageMetaData: StorageData = action.payload;
return this.modelService.loadState()
.pipe(
mergeMap((state: State) => {
const model: Model = AnalysisUtils.convertStateToModel(state, storageMetaData);
return this.modelService.saveModel(model)
.pipe(
map(() => new SavingModelCompleteAction),
catchError((error: Error) => this.createErrorObservableAndLog(error))
);
}),
catchError((error: Error) => this.createErrorObservableAndLog(error))
);
})
);
Also it's a common mistake that constants have the same primitive value. In your case please check that SAVE_MODEL_COMPLETE != SAVE_MODEL. If they have the same primitive value then you keep dispatching the same action.
Upvotes: 4