0

Hi I was reading trought code from angular material google map library. It is all quite clear, but one thing. The code below is what I haven't understood (from map-event-manager.ts).

/** Gets an observable that adds an event listener to the map when a consumer subscribes to it. */
getLazyEmitter<T>(name: string): Observable<T> {
  const observable = new Observable<T>(observer => {
    // If the target hasn't been initialized yet, cache the observer so it can be added later.
    if (!this._target) {
      this._pending.push({observable, observer});
      return undefined;
    }

    const listener = this._target.addListener(name, (event: T) => {
      this._ngZone.run(() => observer.next(event));
    });
    this._listeners.push(listener);
    return () => listener.remove();
  });

  return observable;
}

/** Sets the current target that the manager should bind events to. */
setTarget(target: MapEventManagerTarget) {
  if (target === this._target) {
    return;
  }

  // Clear the listeners from the pre-existing target.
  if (this._target) {
    this._clearListeners();
    this._pending = [];
  }

  this._target = target;

  // Add the listeners that were bound before the map was initialized.
  this._pending.forEach(subscriber => subscriber.observable.subscribe(subscriber.observer));
  this._pending = [];
}

This line, in particular, is not clear to me. Why and how this wires up. And where is the part that let it run back inside of ngZone?

this._pending.forEach(subscriber => subscriber.observable.subscribe(subscriber.observer));

Zone comeback: this._ngZone.run(() => observer.next(event));

Akxe
  • 9,694
  • 3
  • 36
  • 71
  • Have a look at these https://stackoverflow.com/questions/50784775/purpose-of-zone-js-dist-zone-patch-rxjs and https://blog.thoughtram.io/angular/2016/02/01/zones-in-angular-2.html – martin Feb 27 '20 at 14:18
  • @martin I know what is the purpose of zones, I want to know if, and how the `setTarget` wires back to the zone. The `getLazyEmitter` function is explicit about how it got back into the zone, but `setTarget` is not. – Akxe Feb 27 '20 at 15:12

1 Answers1

0

The main purpose of Zone.js is to notify the angular when an async operation happens and based on that angular can decide whether or not to render the UI.

Zone handles most asynchronous APIs such as setTimeout(), Promise.then(),andaddEventListener()`. For the full list, see the Zone Module document. Therefore in those asynchronous APIs, you don't need to trigger change detection manually.

There are still some third party APIs that Zone does not handle. In those cases, the NgZone service provides a run() method that allows you to execute a function inside the angular zone. This function, and all asynchronous operations in that function, trigger change detection automatically at the correct time.

The map related events cannot be detected by angular since these events are considered as custom events and not part of any asynchronous APIs(mentioned above). That's why they are explicitly forcing these events to run inside the zone. So angular can detect these events and trigger change detection accordingly.

For more information refer: https://angular.io/guide/zone

If you go and see the following lines in the /google-map.ts, They are setting the google map instance to setTarget function. So by using the getLazyEmitter, they are attaching map specific listeners to map instance. Again if you check in the google-map.ts, you can see they are attaching listeners by declaring @output events. So each @output already have the map listeners as observable. When a map event occurs, the callback function in the 'this._target.addListener', which is the ngZone will get invoked.

Anto Antony
  • 842
  • 6
  • 12
  • My question is not why there is zone management. (and it is there due to the fact that the markers and other are created outside of zone deliberately). I wanter to know how it got back into zone when the target is set. – Akxe Feb 27 '20 at 14:50