2

I am trying to build an API through which I can get whois detail in the JSON output like below

enter image description here

For this, I installed the whois package from npm (https://www.npmjs.com/package/whois[whois Link]2). I tried to convert the string to object and print it in JSON format but I am not getting any output on the web but it console i can get the data easily. Can you guys please fix my error.

function whoisFunction() {
    var whois = require('whois')
    whois.lookup(url,async function(err, data) {
      try {
        a = await data.split('\n')

      }
      catch (e) {
        console.log(e)
        return e
      }

      c=[]
      for(i = 0; i < a.length; i++){
        c.push(a[i])
      }
      await console.log(typeof (c))
      console.log(c)
      return a
    })
  }
// res.json({'Headers':+whoisFunction()})
  res.status(200).json(whoisFunction())
BIram Firi
  • 99
  • 1
  • 1
  • 8
  • Your `whoisFunction` function doesn't return anything (your anonymous `async function (err, data)` does, but that doesn't do anything), and if it would, then it would have to be a promise which res.json also can't handle. Check out [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – CherryDT Aug 03 '20 at 09:11
  • 1
    Is there a reason for using async/await for `str.split` and `console.log`? – Ian Brindley Aug 03 '20 at 09:12
  • no there is no reason to use async/await but it was done for test only. console.log is done to know if we can see the output in console or not – BIram Firi Aug 03 '20 at 09:34

1 Answers1

1

There are async and awaits sprinkled seemingly randomly all over your function. You should realize that the only thing that is asynchronous here is whois.lookup(). console.log is not asynchronous. Array.prototype.split is not asynchronous. The callback (err, data) => {...} is not asynchronous.

If you want to use the callback pattern, then you need to use res.send() inside of the callback

(err, data) => {
  res.send(data)
}

But we got fed up with callback-patterns because of how messy it is to nest them. So instead we went over to using promises. If you have callbacks but want use promises, then you wrap the callback in a promise. You do it once, and you do it as tight to the offending callback as you can:

  function promisifiedLookup(url){
    return new Promise( (resolve, reject) => {
      whois.lookup(url, function(err, data) {
        if(err) reject(err)
        else resolve(data)
      })
    })
  }

So, to use async/await we need that:

  1. the calling function is declared async
  2. the called function is returning a promise (or else there is nothing to wait for)
async function whoisFunction() {
  let data = await promisifiedLookup(url)  // _NOW_ we can use await
  data = data.split('\n')
  // ...
  return data; // Because this funtion is declared async, it will automatically return promise.
}

If your express-handler is defined as async, then you now can use await here as well:

res.status(200).json(await whoisFunction())
ippi
  • 9,857
  • 2
  • 39
  • 50
  • I am getting error on this ``` return new Promise(resolve, reject) { ^ SyntaxError: Unexpected token { ``` can you help me please – BIram Firi Aug 03 '20 at 11:45
  • Thanks ippi but i could not use await at res.status(200).json(await whoisFunction()) . After removing await i did not get any response in my web – BIram Firi Aug 03 '20 at 12:00
  • You need await there, meaning you either need to make your handler async, or use a .then() chain (or go back to using the callback. Pick your poison.) `whoisFunction().then(data => { res.status(200).json( data ) } )` – ippi Aug 03 '20 at 12:27
  • Hey there what if i need to print the information like this res.status(200).json(await whoisFunction()) I need to know this for further developing – BIram Firi Aug 04 '20 at 07:34
  • 1
    in order to use await, the parent function needs to be declared async, so. with an express handler, it could be something like this: : `app.get("/somewhere", async function(req, res){ .... await .... })`. Make sure you use the async keyword there. – ippi Aug 04 '20 at 07:41
  • 1
    Thanks a lot, mate I just solved this simple shit :) It was all because I did not put async after app.get("/somewhere", which was mistakenly removed while testing – BIram Firi Aug 04 '20 at 07:46