Hi, I'm trying to polling backend using effects.
The problem is I want to re-rendere my app only if server response data changed (so I'm trying to avoid unnecessary state update).
Is it possible? As I know every effect must return action, which triggers reducer, which returns new state. So it either updates state or failes.
effects:
@Effect() solutions: Observable<Action> = this.actions.pipe(
ofType(SolutionActionTypes.GetSolutions),
switchMap(() =>
timer(0, 3000).pipe(
switchMap((action: any) => {
return this.http.get<any>(`/url`, {observe: 'response'}).pipe(
map((res: any) => {
if (res.status === 200) {
if(//data's changed) {
return {type: SolutionActionTypes.SetSolutions, payload: res.body};
} else {
???
}
})
);
})
)
)
);
In our project we created NoOpAction which is then fired and it's not handled by any reducer.
_Note: Don't forget to add some "stop" action to your code, otherwise you will keep pulling forever. But of course it depends on your project, maybe it's desired functionality._
In our project we created
NoOpActionwhich is then fired and it's not handled by any reducer._Note: Don't forget to add some "stop" action to your code, otherwise you will keep pulling forever. But of course it depends on your project, maybe it's desired functionality._
Thanks for answer! That is NoOpAction? Can't find it in docs
You need to create custom one, it's not the part of NgRx.
Something like:
{ type: SomeActionTypes.NoOp }
You need to create custom one, it's not the part of NgRx.
Something like:{ type: SomeActionTypes.NoOp }
I've tried this way. But after { type: SomeActionTypes.NoOp } comes, my reducer updates state. It's ever
case SomeActionTypes.NoOp: {
return {...state};
}
or
default:
return state;
And then all my client side 'jumpes'
Well, you shouldn't handle this action at all, so it will fall into default case in all reducers.
Hi, I've recently wrote an article on polling using ngrx effect. If anyone needs help here is the link: https://bbonczek.github.io/jekyll/update/2018/03/01/polling-with-ngrx.html
@bbonczek I read your article and have some questions, so can you help answer me ?
@dinhlambcs - there is no continuePolling action - there are only StartPolling and StopPolling actions. ContinuePolling$ effect is called on GetSubnetDevicesSucceded/Failed actions. I've pasted a part of an article below:
import { Injectable } from '@angular/core';
import { of } from 'rxjs';
import { Effect, Actions, ofType } from '@ngrx/effects';
import { map, switchMap, catchError, takeWhile, delay } from 'rxjs/operators';
import * as SubnetActions from './subnet.actions.ts';
import SubnetEntry from './subnetEntry.model.ts';
@Injectable()
export class SubnetEffects {
constructor(
private actions$: Actions<SubnetActions.SubnetActionsUnion>,
private http: HttpClient
) {}
private isPollingActive = false; // a flag that indicates whether polling is active or not
// This effect starts polling. There is no other way of initializing polling that calling StartPollingSubnetDevices action.
@Effect()
startPolling$ = this.actions$.pipe(
ofType(SubnetActions.SubnetActionTypes.StartPollingSubnetDevices),
map(() => this.isPollingActive = false), // switch flag to true
switchMap(() => {
return this.http.get<SubnetEntry>('http://localhost:5000/api/subnet').pipe(
switchMap(entries => new SubnetActions.GetSubnetDevicesSucceded({ entries })),
catchError(error => of(new SubnetActions.GetSubnetDevicesFailed({ error })))
),
}),
);
// This effect stops polling. There is no other way to stop polling that calling Stop PollingSubnetDevices action.
@Effect()
stopPolling$ = this.actions$.pipe(
ofType(SubnetActions.SubnetActionTypes.StopPollingSubnetDevices),
map(() => this.isPollingActive = false) // switch flag to false
);
// this effect repeats only if time since last response is at least 5 seconds.
@Effect()
continuePolling$ = this.actions$.pipe(
ofType(
SubnetActions.SubnetActionTypes.GetSubnetDevicesSucceded,
SubnetActions.SubnetActionTypes.GetSubnetDevicesFailed
),
takeWhile(() => this.isPollingActive), // do this only as long as flag is set to true
switchMap(() => {
return this.http.get<SubnetEntry>('http://localhost:5000/api/subnet').pipe(
delay(5000),
switchMap(entries => new SubnetActions.GetSubnetDevicesSucceded({ entries })),
catchError(error => of(new SubnetActions.GetSubnetDevicesFailed({ error })))
);
})
);
}
And I am not sure which version of ngrx was used.
@bbonczek: Need I dispatch startPolling action ? I try to dispatch StartPolling action but api only call once time. I'm using rxjs 6.5 with angular 7, ngrx 7
Most helpful comment
Hi, I've recently wrote an article on polling using ngrx effect. If anyone needs help here is the link: https://bbonczek.github.io/jekyll/update/2018/03/01/polling-with-ngrx.html