However, I am in search of an alternative method - akin to the functionality of angular 1's $watch feature. This is crucial because my complex object can undergo changes through various means, not restricted to just basic input fields.
Recently, while working on a Google Autocomplete Component
, I encountered a similar dilemma: Upon selecting an address from the Google suggestions after typing, it was necessary to update additional fields such as city, province, and zip code.
Following advice from @Günter Zöchbauer, I implemented an observable
to monitor changes within my autocomplete component
. However, a challenge arose when the view failed to reflect these updates, attributed to the concept of Zones. For novice users, detailed explanations about Zones can be found here and here.
The aforementioned sources articulate that:
Application state change occurs due to three primary factors:
Events - User interactions like click, change, input, submit, etc.
XMLHttpRequests - Fetching data from external services
Timers - Usage of methods like setTimeout(), setInterval()
Interestingly, Angular solely focuses on updating the view during these scenarios.
Hence, if
there are alternate methods for modifying my intricate object
It becomes imperative to notify Angular regarding any alterations for synchronization with the updated elements. Here's how I accomplished this:
import {Injectable} from '@angular/core';
import {Observable} from 'rxjs/Observable';
@Injectable()
export class AutocompleteService {
private autocompleteObserver: any;
public autocomplete: any;
constructor(...) {
this.autocompleteObserver = null;
this.autocomplete = Observable.create(observer => {
this.autocompleteObserver = observer;
});
}
public initializeAutocomplete(element): void {
// Core operations here
// ...
// Propagate information to the caller
this.autocompleteObserver.next(addressInformation);
}
Subsequently, in my page's .ts
file:
import { Component, NgZone } from '@angular/core';
import { AutocompleteService } from '../../providers/autocomplete-service/autocomplete-service';
@Component({
templateUrl: 'build/pages/my-new-page/my-new-page.html',
directives: [FORM_DIRECTIVES],
providers: [AutocompleteService]
})
export class MyNewPage {
constructor(..., private autocompleteService : AutocompleteService) {
// Initialization steps
// ...
this.autocompleteService.autocomplete.subscribe((addressInfo) => {
this.ngZone.run(() => {
// Update the form fields, allowing Angular to handle view updates
this.updateAddress(addressInfo);
});
});
}
}
By executing certain actions within an angular zone, you effectively signal Angular to acknowledge potential updates requiring reflection within the application.