Is the code executed within a specific zone, and if it is, what are the reasons and methods for

Recently, I came across the code for the angular material google map library, and most of it made sense to me. However, there is one section in particular that still puzzles me (found in map-event-manager.ts).

/** This method returns an observable that adds an event listener to the map when a user 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 for later addition.
    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 for the manager to bind events to. */
setTarget(target: MapEventManagerTarget) {
  if (target === this._target) {
    return;
  }

  // Remove listeners from the previous target.
  if (this._target) {
    this._clearListeners();
    this._pending = [];
  }

  this._target = target;

  // Subscribe to the cached listeners before the map initializes.
  this._pending.forEach(subscriber => subscriber.observable.subscribe(subscriber.observer));
  this._pending = [];
}

This specific line still confuses me. I'm not sure how this connects or why it works like this. And where exactly does the part come in that makes it run inside ngZone?

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

Regarding Zone:

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

Answer №1

Zone.js serves the main purpose of informing Angular about any asynchronous operations, allowing Angular to decide whether or not to update the user interface accordingly.

Zone handles various asynchronous APIs like setTimeout(), Promise.then(), and addEventListener(). You don't need to manually trigger change detection in these cases. For a complete list, refer to the Zone Module document.

However, there are third-party APIs that Zone does not handle. In such situations, the NgZone service provides a run() method for executing a function within the Angular zone. This automatically triggers change detection at the appropriate time for all asynchronous operations within that function.

Angular cannot detect map-related events as they are custom events and not part of the mentioned asynchronous APIs. Therefore, these events are explicitly executed inside the zone to enable Angular to detect them and trigger change detection accordingly.

For more information, visit: https://angular.io/guide/zone

If you examine the code lines in /google-map.ts, you'll see that the google map instance is set to the setTarget function. Using getLazyEmitter, specific map listeners are attached to the map instance. Furthermore, by declaring @output events in google-map.ts, map listeners are already observable for each output. When a map event occurs, the callback function in 'this._target.addListener', which invokes ngZone, is triggered.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is it possible for a lambda in TypeScript to have access to the class scope but return undefined

In my TypeScript code, I have a class used as a Pipe in Angular 2 to render markdown. It compiles successfully but encounters a runtime exception on a specific line: var Remarkable = require('remarkable'); @Pipe({ name: 'markdown' ...

Angular 10 and Typescript: Variables assigned within the change event become undefined

In my code, I initialize an Algolia input and set an onchange event to it. This initialization takes place in a service. algolia_data; random_var; this.http.post<any>('APIENDPOINT', formData).subscribe(data => { instance = places({ ...

The Interface in TypeScript will not function properly when used on a variable (Object) that has been declared with the value returned from a function

I am currently in the process of developing an application using Ionic v3. Strangely, I am encountering issues with my interface when trying to assign a variable value returned by a function. Here is an example that works without any problems: export int ...

Angular 13: SyntaxError Encountered: Token 'export' Not Recognized

After upgrading Angular from version 12 to 13, I encountered an error when running the app: "Uncaught SyntaxError: Unexpected token 'export'." Here are some additional details for context: In the angular.json configuration file, I had specified ...

What are the best ways to enhance change detection efficiency in Angular?

One issue I am facing involves two components and a service. It appears that when moving from the view of a routed component to elements in different components like a matMenu and an input field, the routed component seems to refresh itself. This becomes p ...

Pictures are shown using the "text/html" layout

I'm having trouble identifying the error and have decided to carefully examine both the client and server code. It seems likely that there is a bug somewhere in Rails. The issue revolves around the photos being displayed in text/html format. Here&apos ...

Utilize an Angular HttpInterceptor to invoke a Promise

I have an angular HttpInterceptor and I am in need of invoking an encryption method that is defined as follows: private async encrypt(obj: any): Promise<string> { However, I am unsure of how to handle this within the HttpInterceptor: intercept(req ...

Top method for continuously updating the position of DOM elements in Angular 2

Currently, I am in the process of developing a game using Angular (version 4). I understand that direct manipulation of the DOM is typically not recommended when working with Angular. However, for the particular functionality I'm trying to achieve, I& ...

What methods can be used in Angular 2 to delete and update row data through HTTP calls?

I am currently working on implementing employee data manipulation functionalities in an Angular application. While I have successfully managed to add new data to the array, I am facing challenges with updating and deleting existing data. Could someone pro ...

Continuously flowing chain of replies from a series of queries using RxJS

I am exploring the world of RxJS and seeking guidance from experienced individuals. My goal is to establish a synchronized flow of responses, along with their corresponding requests, from a stream of payload data. The desired approach involves sending ea ...

Creating a new Angular library with SASS using Angular CLI

I'm currently working on an Angular6 app where I need to create a library. However, after generating the library project, I noticed that Angular CLI is automatically creating components with .css files instead of .scss files. Is there any way I can f ...

Create an interactive slider using only images in an Ionic Angular content display

I need help transforming the images from WordPress into a slider instead of showing them individually. How can I achieve this? <ion-content padding> <div *ngIf="selectedItem" class="selection"> <h2 [innerHTML]="selectedItem.title.rend ...

Is there a way to run a node script from any location in the command line similar to how Angular's "

Currently, I am developing a node module that performs certain functions. I want to create a command similar to Angular's ng command. However, I am facing compatibility issues with Windows and Linux operating systems. Despite my attempts to modify the ...

Angular users should be cautious of the 'grid zero width' warning that may arise when employing ag-Grid's sizeColumnsToFit() on multiple ag-Grids simultaneously

I'm encountering an issue with ag-grid where I see the following warning in the console. Despite conducting some research, none of the solutions I found have resolved my problem. It appears that there may be a memory leak within my application based o ...

Encountering an issue while attempting to make an in-app purchase with Ionic 3 and Cordova - receiving the error message "Sorry, the item you are trying to

In the process of developing my app with IONIC 3 and Angular 4, I have integrated the following Ionic plugin for in-app purchases: https://ionicframework.com/docs/native/in-app-purchase/ Once the plugin was installed, I included the "play_store_key" in t ...

Error: The identifier HTMLVideoElement has not been declared

Encountering an issue while attempting to build my Angular 9 Universal project for SSR: /Users/my-project/dist/server.js:28676 Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__metadata"])("design:type", HTMLVideoElement) ReferenceError: HTMLVideoElem ...

Exploring how to read class decorator files in a Node.js environment

I've developed a custom class decorator that extracts permissions for an Angular component. decorator.ts function extractPermissions(obj: { [key: 'read' | 'write' | 'update' | 'delete']: string }[]) { re ...

Troubleshooting mat-accordion title problem on mobile devices

Despite reading numerous blogs and conducting extensive searches on Google, I am still unable to resolve the CSS issue related to Angular material below. Your assistance in fixing this problem would be greatly appreciated. Desktop view: https://i.stack.im ...

"Losing focus: The challenge of maintaining focus on dynamic input fields in Angular 2

I am currently designing a dynamic form where each Field contains a list of values, with each value represented as a string. export class Field { name: string; values: string[] = []; fieldType: string; constructor(fieldType: string) { this ...

Can you tell me about the interface type format used in the angular cli?

I found myself feeling disoriented while reading the documentation. ng generate interface <name> <type> There was ambiguity on what to input for the type field. Is it supposed to be a string, object, array, or can I define properties like ema ...