0

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 ?

Boudhayan Dev
  • 970
  • 4
  • 14
  • 42

2 Answers2

3

Since response.text() returns a promise, you have to wait for it to resolve to text before sending the response back, otherwise it just sends back an unresolved promise as the payload.

  return fetch(url,config)
    .then((response) => {
      return response.text().then(text => {
        return {
          status: response.status,
          payload: text
        }
      })
    })
helloitsjoe
  • 6,264
  • 3
  • 19
  • 32
2

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
        }
      }
    }
Roamer-1888
  • 19,138
  • 5
  • 33
  • 44
saketh
  • 803
  • 1
  • 10
  • 24