Reputation: 11
When we start polling everything works as expected. Once we stop and start again $continueRefreshStudents stops working. Please check the stackblitz example.
Steps to Reproduce:
https://stackblitz.com/edit/angular-ngrx-polling2?file=src%2Fapp%2Fstate%2Fapp.effects.ts
Upvotes: 1
Views: 333
Reputation: 297
Thank you @Hopey One, same as OP, I was using takeWhile
, but I changed it to use a filter
.
And yes, you can use an effect that calls itself with a retries limit, and without a timer.
deliverMessages$ = createEffect(
() =>
this.actions$.pipe(
ofType(MessageActions.addMessage, MessageActions.addMessageSuccess, MessageActions.addMessageFailed),
withLatestFrom(this.store.select(selectMessages)),
filter(([_action, messages]) => {
return messages.length >= 1;
}),
switchMap(([_action, messages]) => {
const payload = messages[0];
return this.messagesService.addMessage(payload)).pipe(
map(() => {
// If Succeed, remove the message from the queue
return MessageActions.addMessageSuccess(payload)
}),
catchError(error => {
// If Failed, remove the message from the queue (after X retries).
return MessageActions.addMessageFailed({ error, payload })
})
);
}),
// Time span between messages
delay(5000),
),
);
Upvotes: 0
Reputation: 6716
You can move takeWhile
to the inner observable (within mergeMap
) pipe to resolve this issue because in this case, it will complete the inner observable, not the main effect's observable once the isPollingActive
is changed:
public continuePolling$ = createEffect(() =>
this.actions$.pipe(
ofType(appActions.getDataSuccess),
tap(data => console.log('app effect continue polling')),
takeWhile(() => this.isPollingActive),
delay(2000),
mergeMap(() =>
this.appDataSurvice.getData().pipe(
switchMap(data => {
return [appActions.getDataSuccess(data)];
}),
catchError(err => of(appActions.getDataFail(err))),
takeWhile(() => this.isPollingActive), // check again incase this has been unset since delay
)
)
)
);
Upvotes: 0
Reputation: 1816
When you use takeWhile
it completes the observable in your effect once the stop polling changes the isPollingActive
to false. ngrx does not create a new effect each time you start the polling so the subsequent getDataSuccess
actions effects don't happen. You can change your takeWhile
to filter
that way you just ignore the effects when isPollingActive
is false.
I'm not sure however that this is the best approach, an action that has an effect that triggers the same action to happen again. I feel like it would be less confusing to have the start action create an interval
which could fire a continue action and the stop action stop the interval
.
Upvotes: 2