javascriptnode.jspromisenode-fetch

How to resolve nested promise in NodeJs?


I am making using of node-fetch module to make API calls. I have a function that makes all the API calls. And from this function I am returning the status code and the response body. The following code results in empty body -

function makeRequest (url,config) {

  return fetch(url,config)
  .then( (response) => {
    return {
      "status" : response.status,
      "payload": response.text()
    }
  })
  .catch( (error)=>  {
    console.log(error)
    return {
      "status": null,
      "payload" : error.message
    }
  })
}

async function getDestinationToken() {


  const config = {
    method : "POST",
    headers: {
      'Authorization': 'Basic ' + Buffer.from(sDestCredentials).toString('base64')
    },
    body : data
  }

  const url = uaa_service.credentials.url 

  console.log('Getting access Token')

  let response = await makeRequest(url,config)
  console.log("Response from token "+ response)
}

getDestinationToken()

As I understand, response.text() returns a promise. In getDestinationToken() I am waiting for it to fulfill. So, why doesn't it work ? It instead prints an empty body as follows -

       {
          "status" : 200,
          "payload": {}
        }

However, if I do not return a object from the function, as below, the code seems to work.

function makeRequest (url,config) {

  return fetch(url,config)
  .then( (response) => {
    return response.text()
  })
  .catch( (error)=>  {
    console.log(error)
    return {
      "status": null,
      "payload" : error.message
    }
  })
}

In the above case, I am able to see the response payload. However, I cannot use the above method because I need the response.status as well in the calling function.

How to resolve this nested promise ?


Solution

  • as response.text() return promise Using async/await

        return fetch(url,config)
          .then( async (response) => {
            return {
              "status" : response.status,
              "payload": await response.text()
            }
          })
    

    You can mix async/await and .then but it is not recommended because whats-wrong-with-awaiting-a-promise-chain

    pure async/await

        async function makeRequest (url,config) {
          try{
            const response= await fetch(url,config)
            return{
              "status" : response.status,
              "payload": await response.text()
            }
          }
          catch(error) {
            console.log(error)
            return {
              "status": null,
              "payload" : error.message
            }
          }
        }