M.J
M.J

Reputation: 63

Reverse geocoding using Angular

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.

Upvotes: 6

Views: 5275

Answers (2)

user2030471
user2030471

Reputation:

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();
}

Upvotes: 0

Lazar Ljubenović
Lazar Ljubenović

Reputation: 19754

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.

Upvotes: 3

Related Questions