(from Stackoverflow)
I'm using ngx-progressbar and it works fine with http request started from within services, components or resolvers.
Note that no manual triggering of the progress bar (via service, etc) during http requests is needed. It is triggered automatically.
Unfortunately it doesn't work as expected when making an http request from within an NGXS State :
I created for every case a button :
"Make Request (Dispatch to store, w/o zone)"
This does not work, no progress bar appears (or it appears but hangs and does not complete to 100%)
@Action(LoadUrl)
load({ setState }: StateContext<string>) {
return this.http.get<any>('https://jsonplaceholder.typicode.com/posts/1').pipe(tap(res => console.log(res)));
}
"Make Request (Component)"
This does work as expected, progress bar appears
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
// ...
makeRequestComponent() {
this.http.get<any>('https://jsonplaceholder.typicode.com/posts/1').pipe(tap(res => console.log(res))).subscribe();
}
}
"Make Request (Dispatch to store, w/ zone)"
I asked the developer of ngx-progressbar and he actually found the issue and solved it by wrapping the http call inside zone. This does work, progress bar appears :
@State<string>({
name: 'testState',
defaults: ''
})
export class TestUrlState {
constructor(private http: HttpClient, private zone: NgZone) { }
@Action(LoadUrl)
load({ setState }: StateContext<string>) {
this.zone.run(() => {
this.http.get<any>('https://reqres.in/api/users?delay=2').pipe(
tap(res => console.log(res))
).subscribe();
});
}
}
Please add an option to turn off the 'run outside of zone' feature.
The state should not deal with ui related items. Use the actions stream to handle these .
@amcdnl I think that this is a but different. The ngx-progressbar is expecting the angular HttpInterceptor to be executed in the angular zone but because our actions are executing the http call outside of the zone this does not work correctly.
Do you think that we could provide the circumvention of the general 'run outside of the angular zone' approach as a module or @Action option?
Reopening until we get an answer to my question above, just so that this doesn't fall off the radar.
@markwhitfeld we are also stumbling on this issue... but while running our Protractor E2E tests,
due to the fact that handling of an NGXS action occurs outside the Angular Zone.
@Action(GetMessages, { cancelUncompleted: true })
getMessages(ctx: StateContext<MessagesModel>) {
return this.myService.getMessages(ctx.getState().userId).pipe(
tap(messages => {
ctx.setState({
...ctx.getState(),
pending: false,
messages
});
})
);
}
In this example the whenStable is called before ctx.setState, causing protractor to fail unless we manually add browser.sleep or waits.
We tried removing the runOutsideAngular call and that fixed the issue for us.
Today we can use outsideZone in config, this will be released in 3.4.0
Most helpful comment
@amcdnl I think that this is a but different. The ngx-progressbar is expecting the angular HttpInterceptor to be executed in the angular zone but because our actions are executing the http call outside of the zone this does not work correctly.
Do you think that we could provide the circumvention of the general 'run outside of the angular zone' approach as a module or
@Actionoption?