I have a little problem with my function that should check if domains with the specific name are available under few top level domains. When I call this function like whois("example434"); it returns undefined instead of array ["example424.org", ..., "example424.com"] . How to modify the function to solve this problem? Where I make mistake?
function whois (name, domains = '*') {
if ( typeof domains == 'Object' && domains.length > 0 ) {
var TLD = domains;
} else {
var TLD = ['.com','.net','.org','.edu','.gov', '.biz', '.info', '.mobi', '.me', '.tv', '.info', '.io'];
}
var available = [];
Promise.resolve(
Promise.map(TLD, function(domain) {
return dns.resolve4(name + domain, (err, addresses) => {
if (!addresses || addresses.length <= 0 ){
console.log(name + domain);
available.push(name + domain);
}
});
})
).then(()=>{
console.log(available);
return available;
});
}
Your main issues are:
whois
never returns a value, hence you get undefined
typeof domains
can never be Object
, did you mean object
- even that is not a good way to determine if a vlaue is an Array
Your title includes the phrase: promise still works asynchronous - well, yes, were you expecting something else? Asynchronous code is asynchronous, and nothing will change that
Anyway, your code with the issues annotated:
function whois(name, domains = '*') {
// Issue 4
if (typeof domains == 'Object' && domains.length > 0) {
var TLD = domains;
} else {
var TLD = ['.com', '.net', '.org', '.edu', '.gov', '.biz', '.info', '.mobi', '.me', '.tv', '.info', '.io'];
}
var available = [];
// Issue 2
Promise.resolve(
Promise.map(TLD, function(domain) {
// Issue 1
return dns.resolve4(name + domain, (err, addresses) => {
if (!addresses || addresses.length <= 0) {
console.log(name + domain);
available.push(name + domain);
}
// possible error: if there's an error (err is not falsey) does that really mean the domain is available?
});
})
).then(() => {
console.log(available);
return available;
});
// Issue 3
}
You'll want to promisify the dns.resolve4 function, const resolve4 =
in the code below.
I know that bluebirdjs and later nodejs have built in promisify methods however the logic for those would mean an err
rejects the promise
which you probably do not want.
Also, you want to resolve differently for different successful results, so, best to promisify "by hand" as it were
Use Array.isArray
to determine if TLD is an Array
function whois (name, TLD) {
// if TLD isn't an array, use the default array
if (!Array.isArray(TLD)) {
TLD = ['.com','.net','.org','.edu','.gov', '.biz', '.info', '.mobi', '.me', '.tv', '.info', '.io'];
}
// prepare the list of full domains to check
const domains = TLD.map(domain => name + domain);
const resolve4 = domain => new Promise(resolve => {
dns.resolve4(domain, (err, addresses) => {
if (addresses && addresses.length) {
// domain resolves - so it's not available
resolve(false);
}
// uncomment the next two lines if you want an error to indicate the domain is NOT available
//else if (err) {
// resolve(false);
} else {
// it's available
resolve(domain);
}
});
});
return Promise.map(domains, resolve4)
// filter for available domains (i.e. return an array of non-falsey results)
.then(results => results.filter(domain => domain));
}