20

Referring to this documentation I am getting the ip address from domain name inside console.log the code looks like so:

const dns = require('dns');

dns.lookup('iana.org', (err, address, family) => {
  console.log('address: %j family: IPv%s', address, family);
});

Output of console.log is fine. However I can't get address outside that scope. The return statement of the dns.lookup function is an object.

What I've tried so far:

const ipAddress = dns.lookup("www.aWebSiteName.am", (err, address, family) => {
  if(err) throw err;
  return address;
});

console.log(ipAddress);

I am getting:

GetAddrInfoReqWrap {
  callback: [Function],
  family: 0,
  hostname: 'www.aWebSiteName.am',
  oncomplete: [Function: onlookup] }

5 Answers 5

26

You can not because dns.lookup() function is working async.

Though the call to dns.lookup() will be asynchronous from JavaScript's perspective, it is implemented as a synchronous call to getaddrinfo(3) that runs on libuv's threadpool. This can have surprising negative performance implications for some applications, see the UV_THREADPOOL_SIZE documentation for more information.

There are different ways to take the result. Welcome to JS world!

Callback

dns.lookup("www.aWebSiteName.am", (err, address, family) => {
  if(err) throw err;
  printResult(address);
});

function printResult(address) {
   console.log(address);
}

Promise

const lookupPromise = new Promise((resolve, reject) => {
    dns.lookup("www.aWebSiteName.am", (err, address, family) => {
        if(err) reject(err);
        resolve(address);
    });
});

lookupPromise().then(res => console.log(res)).catch(err => console.error(err));

Promise async/await

async function lookupPromise() {
    return new Promise((resolve, reject) => {
        dns.lookup("www.aWebSiteName.am", (err, address, family) => {
            if(err) reject(err);
            resolve(address);
        });
   });
};

try {
    const address = await lookupPromise();
} catch(err) {
    console.error(err);
}
Sign up to request clarification or add additional context in comments.

Comments

6

This is normal because "dns.lookup" is executed asynchronously

So you can't just use the returned value of the function

You need to do your logic inside the callback or make an helper to promisfy the function and execute it in async function with await.

Something like this:

function lookup(domain) {
  return new Promise((resolve, reject) => {
    dns.lookup(address, (err, address, family) => {
      if (err) {
        reject(err)
      } else {
        resolve({ address, family })
      }
    })
  })
}

async function test() {
  let ipAddress = await lookup(("www.aWebSiteName.am");
}

EDIT:

You can also use:

const dns = require('dns');
dnsPromises = dns.promises;

async function test() {
  let data = await dnsPromises.lookup(("www.aWebSiteName.am");
}

Comments

1

NodeJS already has a version with promises.

Inside a lambda:

import { promises as dnsPromises } from 'dns';
 
export const handler = async(event) => {
    return await dnsPromises.lookup('foo.bar.example.com');
};

Comments

0

The dns lookup happens async and the value can be set when the callback is fired. You only reach the point where you have the address in the callback. Putting a variable around it will not wait for the callback to fire and therefor it will not be availlable.

dns.lookup("www.aWebSiteName.am", (err, address, family) => {
  if(err) throw err;
   // Here you have access to the variable address
   // Execute code or call function which needs the address here
});

Comments

0

Even it was an old question, I would like to give my point of you.

Searching for examples of dns.lookup() function I always found them reporting some console.log() outputs inside the .lookup method.

But I was looking for a simple true/false response value. Something like: I've this Url, check me if it is on the internet or not.

Originally my solution gave back a true/false. I adapted it to give back the address, as you asked in your question.

So here is my personal implementation.

async function getAddr(href) {
  console.log("Check =>", href);
  let resVal = undefined;
  await dns.lookup( new URL(href).host , (err, address, family) => {
    return resVal = (err) ? false : address;
  });

  await new Promise((resolve, reject) => setTimeout(resolve, 1000));
  console.log("Check =>", href, "is host Good? [", resVal, "]");
  return resVal;
}

I think this is the simplest way to manage a personalized answer. No matter your needs, you can immediately adjust and personalize it.

I left the console.log() statements in place just to quick test the scripts.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.