0

I'm new to Node JS and I can't seem to figure out why i'm getting an 'undefined' when using an async function. I've wrapped the async function in a promise and it resolves after an API request has been completed.

   let req = (url) => new Promise((resolve, reject) => {
    var options = {
        'method': 'GET',
        'url': url,
        'headers': {
            'Content-Type': 'application/json'
        }
    }

    request(options, function (error, response) { 
        if (error) {
            reject(error)
        } else {
            resolve(response.body)
        }
    })
})
.then((results) => {
    //console.log(results) //this shows the results when uncommented!
    console.log('request has been completed')
})
.catch((error) => {
    console.log(error)
})

Here is the function that triggers the 'req' function and then says 'undefined' when I log the value:

let getAllData = async (url) => {
    var endpoint = `${url}?apikey=${settings.api_key}`
    let res = await req(endpoint)
    console.log('run after request') //successfully runs after request is resolved above
    console.log(res) //gives me 'undefined' 

}

Here is my output.

request has been completed
run after request
undefined

What am I doing wrong here?

Yehudah
  • 65
  • 1
  • 5

2 Answers2

1

You are using a .then / .catch as part of the function definition - which does not make sense. Those constructs should be used as part of the function execution.

Define your function like this:

let req = (url) => new Promise((resolve, reject) => {
    var options = {
        'method': 'GET',
        'url': url,
        'headers': {
            'Content-Type': 'application/json'
        }
    }

    request(options, function (error, response) { 
        if (error) {
            reject(error)
        } else {
            resolve(response.body)
        }
    })
})

Then, at execution time, you do this:

let getAllData = async (url) => {
    var endpoint = `${url}?apikey=${settings.api_key}`
    let res = await req(endpoint)

    console.log('run after request')
    console.log(res) // should give response.body 

}

OR you do this:

let getAllData = async (url) => {
    return new Promise((resolve, reject) => {
        var endpoint = `${url}?apikey=${settings.api_key}`
        req(endpoint)
        .then(res => {
            console.log('run after request')
            console.log(res) // should give response.body

            resolve(res)
        })
        .catch(err => {
            console.error(err)
            reject(err)
        })
    })
}

Basically, define the function and then... either call it with async/await syntax, or with promise-style .then/.catch syntax.

Vish Desai
  • 1,141
  • 7
  • 8
0

Return a value in your then or remove the then and catch block and do this instead when you call the promise with await:

let res = await req(endpoint).catch(err => console.log(err));

schankam
  • 10,778
  • 2
  • 15
  • 26
  • Thanks. I tried returning the value in the 'then' and it worked. Is is best practice to have the value returned in the 'then' or in the line where I call the promise with awai? – Yehudah May 02 '20 at 11:42
  • By using "then", you are actually running the promise. So depending on what you want to do, you can do this, but in your case you can just remove the then/catch blocks and just use "await". – schankam May 02 '20 at 11:47