vishnu
vishnu

Reputation: 4599

Reverse geocoding using Angular 2

I am using reverse geocoding using Angular 2, it is working fine but i am not able to set the values(i.e, city name) using service(setter and getter)

import { ShareService } from './services/ShareService';
class ConferenceApp {
   constructor(public shareService: ShareService){
     this.getGeoLocation();

   }
    public getGeoLocation(){
          if (navigator.geolocation) {
              var options = {
                enableHighAccuracy: true
              };

              navigator.geolocation.getCurrentPosition(position=> {
                this.lat = position.coords.latitude;
                this.long = position.coords.longitude;
                let geocoder = new google.maps.Geocoder();
                let latlng = new google.maps.LatLng(this.lat, this.long);
                let request = {
                  latLng: latlng
                };   

                  geocoder.geocode(request, function(results, status) {
                    if (status == google.maps.GeocoderStatus.OK) {
                      if (results[0] != null) {
                       let city = results[0].address_components[results[0].address_components.length-4].short_name;                      

                       this.shareService.setLocationDetails(city);


                      } else {
                        alert("No address available");
                      }
                    }
                  });

              }, error => {
                console.log(error);
              }, options);
          }
        }
}

if i try to set using service, this.shareService.setLocationDetails(city); I am getting error saying,

app.ts:303 Uncaught TypeError: Cannot read property 'shareService' of undefined

The service:

locationObj: any;
setLocationDetails(locationObj){
      this.locationObj = locationObj;
    }
    getLocationDetails(){
      return this.locationObj;
    }

Upvotes: 5

Views: 6934

Answers (3)

trsft
trsft

Reputation: 139

I have not enough reputation to comment :-(, so I will answer Usman Iqbal's question as an answer. Maybe some admin can transform this into a comment.

Implicit callback functions create a structure named closure: An object containing the actual function as well as its creation context. That context contains all the variables "surrounding" the callback as well as their values at the time the function was created. The closure does not contain the value of the context's this, because it is an object itself and has its own this at the time the callback is executed.

To make the this of the creation context directly available, arrow functions by definition handle this such that it is not the closure's this, but the this of the creation context. Without arrow functions you can achieve the same by explicitly copying the surrounding this into the context of the closure:

let self = this; // this of the creation context

geocoder.geocode(request, function (results, status) {
    if (status == google.maps.GeocoderStatus.OK) {
        if (results[0] != null) {
            ...
            // access the surrounding this via self
            self.shareService.setLocationDetails(city);
        } 
        ...
    }
});

Upvotes: 0

micronyks
micronyks

Reputation: 55443

I think everything is fine. But, I'd suggest you to use arrowfunction()=> as shown below,

// Removed function keyword and added arrow function
geocoder.geocode(request, (results, status) => {
  if (status == google.maps.GeocoderStatus.OK) {
    if (results[0] != null) {
      let city = results[0].address_components[results[0]
                .address_components.length-4].short_name;
      this.shareService.setLocationDetails(city);
    } else {
      alert("No address available");
    }
  }
});

Upvotes: 6

Meegh
Meegh

Reputation: 39

geocoder.geocode(request, (results, status) => {....} showed an error on 'results' saying that {'latLng' : latlng} does not correspond to results type.

Solution:

  var geocoder = new google.maps.Geocoder();
  var latlng = new google.maps.LatLng(this.eventLat, this.eventLng);
  let request = {
    location: latlng
  };
  geocoder.geocode(request, function (results, status) {
    if (status == google.maps.GeocoderStatus.OK) {
        if (results[1]) {
            console.log(results[1].formatted_address);

        } else {
            console.log('Location not found');
        }
    } else {
        console.log('Geocoder failed due to: ' + status);
    }
});

Upvotes: 0

Related Questions