Web Nexus
Web Nexus

Reputation: 1158

Angular 7 data binding being delayed

I am having an issue with Angular's data binding being delayed.

When the value of this.notAvailable is changed the [class.hide] doesn't update on the frontend until ~5 seconds after the code has been run.

The console.log results show immediately with the correct values, this has really been bugging me as to why this is happening.

The code is as follows:

xxx.ts

getPostcodeGeo(postcode) {
  postcode = postcode.replace(' ', '');
  this.geocoder.geocode({'address': postcode}, (result, status) => {
    if (status === google.maps.GeocoderStatus.OK) {
      this.notAvailable = false;
      console.log(this.notAvailable);
    }
    if (status === google.maps.GeocoderStatus.REQUEST_DENIED) {
      this.notAvailable = true;
      console.log(this.notAvailable);
    }
  });
}

xxx.html

<div [class.hide]="notAvailable">
  <span>Unable to find address</span>
</div>

At first I thought is was to do with the geocoder taking a bit of time, but then I added the console.logs to see if there is a delay in the console.

Am I doing something wrong here?

Any help would be greatly appreciated.

Upvotes: 0

Views: 1378

Answers (1)

Daniel W Strimpel
Daniel W Strimpel

Reputation: 8470

As mentioned above, the issue is that the callback code passed to the this.geocoder.geocode(...) method is being executed outside of the Angular zone. When this happens, Angular is not aware of the changes to the this.notAvailable property until something else triggers Angular to do a change detection cycle down the road. To fix this, you will need to get a reference to the Angular zone and wrap the code making changes so that Angular knows to do a change detection cycle.

constructor(private ngZone: NgZone) {}

...

getPostcodeGeo(postcode) {
  postcode = postcode.replace(' ', '');
  this.geocoder.geocode({'address': postcode}, (result, status) => {
    this.ngZone.run(() => {
      if (status === google.maps.GeocoderStatus.OK) {
        this.notAvailable = false;
        console.log(this.notAvailable);
      }
      if (status === google.maps.GeocoderStatus.REQUEST_DENIED) {
        this.notAvailable = true;
        console.log(this.notAvailable);
      }
    });
  });
}

Upvotes: 2

Related Questions