Reputation: 21339
I have a GPS plugin providing locations out of an angular zone. The changes are therefore not detected by angular and the view keeps stuck with the same values.
Of course, I could subscribe to this observable from the controller and do something like that.
$mySourceOutOfZone.subscribe((value)=>{
this.zone.run(() => {
this.value = value;
});
})
And the view will simply use the value like:
<span>{{value}}</span>
But I would like to avoid having to subscribe to the controller and using the imperative style way.
How could I have this observable to run inside an angular zone?
Upvotes: 11
Views: 5129
Reputation: 21339
It seems there is a plugin dedicated to rxjs and zones:
The zone can be bound to any rxjs stream using
.enterZone(this.ngZone)
or using the pipe operator:
.pipe(enterZone(this.ngZone))
Upvotes: 6
Reputation: 898
When using RxJs 6+, a custom pipe operator can wrap the observable's behavior in a zone.run()
for the specified zone.
import { Observable, OperatorFunction } from 'rxjs';
import { NgZone } from '@angular/core';
export function runInZone<T>(zone: NgZone): OperatorFunction<T, T> {
return (source) => {
return new Observable(observer => {
const onNext = (value: T) => zone.run(() => observer.next(value));
const onError = (e: any) => zone.run(() => observer.error(e));
const onComplete = () => zone.run(() => observer.complete());
return source.subscribe(onNext, onError, onComplete);
});
};
}
The operator can then be added to an observable, letting you be explicit about when to change zone contexts.
return exampleObservable.pipe(
runInZone(this.zone)
);
Upvotes: 22
Reputation: 1711
You can also try this patch.
Add this line inside polyfills.ts
after import zone.js
.
import `zone.js/dist/zone-patch-rxjs`;
So subscription callback
will run in the zone when it call .subscribe
.
Upvotes: 0