6

I am using reverse geocoding in Angular app.

The needed script is added in index.html

<script async defer src="https://maps.googleapis.com/maps/api/js">
</scrip>

and the component file looks like this

import { Component } from '@angular/core';
declare const google: any;

export class MapComponent {

  lat;
  lng;
  address;

  constructor() {
    this.locate();
  }

  public locate() {
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(
        position => {
          this.lat = position.coords.latitude; // Works fine
          this.lng = position.coords.longitude;  // Works fine

          let geocoder = new google.maps.Geocoder();
          let latlng = new google.maps.LatLng(this.lat, this.lng);
          let request = {
            latLng: latlng
          };

          geocoder.geocode(request, (results, status) => {
            if (status == google.maps.GeocoderStatus.OK) {
              if (results[0] != null) {
                this.address = results[0].formatted_address;  //<<<=== DOES NOT WORK, when I output this {{ address }} in the html, it's empty
                console.log(this.address);  //<<<=== BUT here it Prints the correct value to the console !!!
              } else {
                alert("No address available");
              }
            }
          });
        },
        error => {
          console.log("Error code: " + error.code + "<br /> Error message: " + error.message);
        }
      );
    }
  }
}

and in the component html file, It's supposed to output the address

<div>{{ lat }}</div>        // Works fine
<div>{{ lng }}</div>        // Works fine 
<div>{{ address }}</div>    // Deosn't Work, EMPTY

but it's always empty, however this line

console.log(this.address);

printed the correct value.

1
  • Thanks, your code helped me kick start my geocoder! Commented Dec 5, 2020 at 16:52

2 Answers 2

3

There are two possibilities that I see here but cannot confirm without a reproduction, so I'll list them both.

1) You're not in Angular's zone

The code which changes the variable for displaying is not being executed inside Angular's zone. This tends to happen when using callbacks from third party libraries like you're doing here.

To fix, inject the NgZone and wrap any changes you want to see reflected in the UI with this.ngZone.run, like in the following snippet.

constructor(private ngZone: NgZone) {}

locate() {
  /* ... */
      this.ngZone.run(() => {
        this.location = results[0].formatted_address
      })
  /* ... */
}

2) Wrong this

Somewhere along the way, you've lost the this which points to class instance, and you're instead writing the result into something else. You console.log works because that's also logging the wrong this, and Angular shows nothing because the actual property was not changed.

Sign up to request clarification or add additional context in comments.

2 Comments

You saved my life :)
@M.J, for me it is showing an error as follows ERROR ReferenceError: google is not defined
0

Your component may not have been initialized when you're setting this.location as Angular doesn't control when the constructor will be called.

You should try placing locate call in ngOnInit which guarantees that your component is ready to display data bound properties:

ngOnInit() {
  this.locate();
}

2 Comments

You're not in Angular's zone is correct answer here
Thank you, I tried placing the call in ngOnInit and it didn't work, but the ngZone solved the issue.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.