1

I would like to write a function that returns data from the google places API in node.js. The function is defined as seen below:

function getAddress(placeName) {
  return new Promise((resolve, reject) => {
    return axios.get('https://maps.googleapis.com/maps/api/geocode/json?address=' + placeName + '&key=MyAPIKey').then(response => {
      const placeID = response.data.results[0].place_id
       return axios.get('https://maps.googleapis.com/maps/api/place/details/json?placeid=' + placeID + '&key=MyAPIKey').then(response => {
          resolve(response.data.result)
          return response.data.result // here i would like to return the data.result
        }).catch(err => {
          console.error(err);
        });
    }).catch(err => {
      reject(err);
    });
  });
}

I want to use the function and get a return value. I have tried with the code below, but i get the error 'Promise pending'

const address = getAddress('someName').then(address => {
    phone: address.formatted_phone_number
  }).catch(err => {
    console.error(err)
  })

So how do i construct the function, so it returns the data?

john
  • 395
  • 2
  • 4
  • 13

2 Answers2

1

You are returning the result of axios.get before you ever resolve your promise, so it never resolves. You should only be returning resolve/reject, anything else and your promise will never resolve (unless resolve/reject was called before you return).

function getAddress(placeName) {
  return new Promise((resolve, reject) => {
    axios.get('https://maps.googleapis.com/maps/api/geocode/json?address=' + placeName + '&key=MyAPIKey').then(response => {
      const placeID = response.data.results[0].place_id
       axios.get('https://maps.googleapis.com/maps/api/place/details/json?placeid=' + placeID + '&key=MyAPIKey').then(response => {
          return resolve(response.data.result)
        }).catch(err => {
          return reject(err)
        });
    }).catch(err => {
      return reject(err);
    });
  });
}
Get Off My Lawn
  • 34,175
  • 38
  • 176
  • 338
0

Promise is an asynchronous concept, and return statements in functions are synchronous. In your example new Promise(...) branches out of the synchronous execution flow, so whatever results are produced within the promise cannot be accessed in a synchronous fashion.

Your function returns a promise and the only way to work with asynchronous results within it is by using its then or catch methods.

Long story short, there is a certain way to code when using asynchronous API, which favors event-driven approach. Consider the following architecture:

var eventBus = new EventEmitter()

eventBus.on('address', (addr) => {
  // do something with address
})

asyncGetAddress().then(addr => {
  eventBus.emit('address', addr)
})

See also: https://nodejs.org/api/events.html

krukid
  • 4,285
  • 5
  • 31
  • 30
  • Just to be clear: would it in any way be possible to get the data in this way: const somePlaceAddress = getAddress(('somePlace')) – john Jul 21 '17 at 17:17
  • Not if the result of `getAddress` is a promise (and it is in your case) – krukid Jul 21 '17 at 17:20
  • I think you're being confused by the effect of all those `return` statements in your code. Apparently you expect them to do something they really don't. In fact, they have no effect whatsoever in your case. The code would have the same behavior if you removed them altogether (except the `return new Promise`, of course). – krukid Jul 21 '17 at 17:27