Ad

Need Help Understanding The Scope Of This Javascript Variable

In javascript, within a VueJS SPA, I'm trying to create a method that will allow me to reduce redundant code by passing the Google Maps Places Service only a place_id and the fields I would like returned.

getPlaceDetails (place, fields) {
  this.$refs.mapRef.$mapPromise.then((map) => {
    var placesServices = new window.google.maps.places.PlacesService(map)
    placesServices.getDetails({ placeId: String(place.place_id), fields: fields }, (result, status) => {
      if (status === window.google.maps.places.PlacesServiceStatus.OK) {
        alert(JSON.stringify(result))
        return result
      }
    })
  })
}

I'm calling the above method from within another method:

var place = this.getPlaceDetails(place, ['name', 'geometry', 'place_id'])

It is invoked successfully... and the alert shows the desired JSON.. but place is null. I've tried using

var vm = this

above

var placesServices

and assigning the result to an app level variable... even inside of a .then after the first promise... like so:

getPlaceDetails (place, fields) {
  this.$refs.mapRef.$mapPromise.then((map) => {
    var vm = this
    var placesServices = new window.google.maps.places.PlacesService(map)
    placesServices.getDetails({ placeId: String(place.place_id), fields: fields }, (result, status) => {
      if (status === window.google.maps.places.PlacesServiceStatus.OK) {
        alert(JSON.stringify(result))
        vm.tempPlace = result
      }
    })
  }).then(function () {
    return this.tempPlace
  })
}

How can I get the method to return the result object??

Ad

Answer

Promises

A promise is an object that will resolve (or reject) in some point in the future. This is necessary to execute asynchronous tasks (e.g. http-calls) that take an undefined amount of time to finish.

Promises can be chained i.e. get executed one after another. This is what the .then method does. With .then you pass a function that will be executed as soon as the promise is finished. This function will receive the object that was returned by the previous promise.

Your method

getPlaceDetails (place, fields) {
    return this.$refs.mapRef.$mapPromise.then((map) => {
        var vm = this;
        var placesServices = new window.google.maps.places.PlacesService(map);
        placesServices.getDetails({ placeId: String(place.place_id), fields: fields }, (result, status) => {
            if (status === window.google.maps.places.PlacesServiceStatus.OK) {
                alert(JSON.stringify(result));
                return result;
            }
        });
    });
}

This Method will return a promise that - at some point in the future - will yield the desired result.

When you want to call the method you get that promise and have to handle it, again by passing a function (using .then) that will be executed once the result is ready.

this.getPlaceDetails(...).then((result) => {
    // handle your result
}}

Alternatively you could use the await operator to wait until the promise is finished: var place = await this.getPlaceDetails(...);

Ad
source: stackoverflow.com
Ad