Reverse geocoding using Angular
Asked Answered
A

2

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.

Abeyance answered 17/12, 2017 at 8:31 Comment(1)
Thanks, your code helped me kick start my geocoder!Griseous
F
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.

Fibriform answered 17/12, 2017 at 8:46 Comment(2)
You saved my life :)Abeyance
@M.J, for me it is showing an error as follows ERROR ReferenceError: google is not definedHomogenize
E
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();
}
Epididymis answered 17/12, 2017 at 9:7 Comment(2)
You're not in Angular's zone is correct answer hereRubbico
Thank you, I tried placing the call in ngOnInit and it didn't work, but the ngZone solved the issue.Abeyance

© 2022 - 2024 — McMap. All rights reserved.