Angular 2 : what make a service to be "Outside" angular zone?
Asked Answered
F

3

5

After having same issues as many people on StackOverflow i didn't manage to understand what is an "Outside angular zone" Service ?

I've checks all existing questions around this subject, and it's exactly why i needer to ask this one :

Code Example in any component with default ChangeDetectionStrategy : (considering this.value referenced in view)

this.myService.method().subscribe(e => {
    this.value = e;
  });

Is the given service is not "Outside angular zone", the view is refreshed, on the other hand, if it's "Outside angular zone", the view is not refreshed, unless we call ChangeDetectorRef.detectChanges().

So the question is : what the condition to know if a service is Inside or Outside "Angular Zone" ?

Fairleigh answered 6/6, 2017 at 13:42 Comment(0)
B
8

The code you want is NgZone.isInAngularZone(). This will tell you whether or not it's executing there.

Source: hours of banging my head against the wall reading Angular docs before writing this.

Additionally, you can inject NgZone into your service and try using this.ngZone.run(() => yourSubscriberCallback()) which should help, though I'm having very mixed results attempting this.

EDIT: Okay, I managed to get my stuff working, let's see if it helps you.

In my case I was using a third party library that included a listener for changes. I was using an RXJS BehaviorSubject to propagate these changes to various components via a service, but the changes weren't being picked up.

It turns out that this was because the method I used in the listener was executing outside of the AngularZone.

At first I was doing this:

export class Service {

  public BehaviorSubject<Thing> thingSubject = new BehaviorSubject<Thing>(new Thing());

  constructor(private ngZone:NgZone) {
    thirdPartyLibrary.listen(ngZone.run(() => myCallback.bind(_this)));
  }

  ...

}

And myCallback was doing:

myCallback(thing) {
  this.thingSubject.next(thing);
}

Turns out this didn't seem to execute within the Angular Zone correctly. I changed my code to this though and it worked:

export class Service {

  public BehaviorSubject<Thing> thingSubject = new BehaviorSubject<Thing>(new Thing());

  constructor(private ngZone:NgZone) {
    thirdPartyLibrary.listen(myCallback.bind(_this));
  }

  myCallback(thing) {
    this.ngZone.run(() => this.thingSubject.next(thing));
  }

}

After doing that all my subscribers received the message within the Angular Zone and triggered the expected updates.

Brickbat answered 11/8, 2017 at 23:11 Comment(0)
D
0

As far as I know, it is not possible to check whether something runs "Inside" or "Outside" angular zone. If you use zone.runOutsideAngular it runs outside your zone. Second comes to my mind: Why would you want to know?

Dame answered 6/6, 2017 at 14:4 Comment(2)
Not necessarily at runtime. I want to know what kind of service are capable to auto update the view and what kind of services are not.Fairleigh
Everthing you will run in zone.runOutsideAngular won't update the view.Dame
F
0

It looks like I found my responses by myself, but i Hope it will be an assistance for other people :

an "Outside Angular Zone" service is a class that was not instantiate inside Angular Context. Many libraries using static accessors are susceptible to be in this case, here's an example :

http://techqa.info/programming/question/34592857/view-is-not-updated-on-change-in-angular2

My luck is that it was the same library used. As described in this external resource, manage to instantiate the external library object would resolve view refresh issue and let this service became an "Inside Angular zone" one.

Fairleigh answered 6/6, 2017 at 15:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.