Reputation: 4521
I'm not sure if the title of this post explains my problem well, but here is my situation.
I have a tree with lazily loaded children. When you expand a tree node, it dispatches a LoadChildrenAction
with the parent node that was just expanded as a payload.
Here is my effect:
@Effect()
loadChildren$: Observable<Action> = this.actions$
.ofType(ActionTypes.LOAD_CHILDREN).switchMap((action: LoadChildrenAction) => {
return this.categoryService.loadChildren(action.payload).map(
children =>
new LoadChildrenSuccessAction({
parent: action.payload,
children
})
);
});
If I expand just a single node, this works perfectly. The LoadChildrenSuccessAction
is dispatched and in my reducer I update the tree.
However, if I expand a node, then expand another node before the first operation completes, only the last operation ever completes.
That is to say, I expand one node, then immediately expand another node while the first node is still loading. The second tree node gets updated with its child content, but the first one never does. In fact, two LoadChildrenAction
s get dispatched - one for each expansion - but only one LoadChildrenSuccessAction
ever gets dispatched.
If I put a console.log
inside my categoryService.loadChildren
function, it gets logged twice - so the service is getting called twice. But only one action gets dispatched, so I lose the first action - it just never completes.
Any idea what I'm doing wrong here?
Upvotes: 2
Views: 352
Reputation: 191799
This is because you are using .switchMap
which will cancel a previous observable if it has not completed before the next observable is emitted. The first loadChildren
is called, and when the second is called before it completes the first call is canceled.
You can use .mergeMap
instead which will allow you to run multiple calls of loadChildren
in parallel. Just keep in mind that this removes the somewhat automatic canceling of duplicate requests so if you need functionality like that you'll have to handle it on your own.
Upvotes: 4