I created a function that prompts the user for a URL, then validates that the entered input is actually a URL. The issue is, when I call this function from my other function, I have been able to get it to wait for user input before but it doesn’t go through the entire condition statement before returning the url.
How do I use promises/async/await to wait till my requestSiteURL() function has completed its condition statement, before setting the variable in getURL()?
const readline = require('readline').createInterface({
input: process.stdin,
output: process.stdout,
});
// request url from user in command prompt
const requestSiteURL = () => {
return new Promise((resolve, reject) => {
readline.question('Please type url: ', async (url) => {
if (validUrl.isUri(url)) {
readline.close();
resolve(url);
// if user types no, then use base url
} else if ('No' || 'no' || 'NO') {
url = URL;
resolve(url);
} else {
reject(
console.log(
'Please type in a valid URL or type "no" to use base url.'
)
);
requestSiteURL();
}
});
});
};
// grabs all urls from original link and returns array
const getURLS = async () => {
let url = await requestSiteURL();
url = deleteFowardSlash(url);
try {
const res = await axios.get(url);
const data = res.data;
const $ = cheerio.load(data);
const urlQueue = [];
// finds all absolute links and pushs to urlQueue array
$("a[href^='http']").each((i, elem) => {
let link = $(elem).attr('href');
//checks to make sure link isnt any duplicate links in urlqueue array
link = deleteFowardSlash(link);
uniqueLinkChecker(link, urlQueue);
});
return urlQueue;
} catch (err) {
console.error(err);
return response.status(400).send(err);
}
};
Advertisement
Answer
I think it is a matter of syntax. Here I switched the original line to use the Promise constructor correctly. Promise mdn
// request url from user in command prompt
const requestSiteURL = () => {
return new Promise((resolve, reject) => {
readline.question('Please type url: ', async (url) => {
if (validUrl.isUri(url)) {
readline.close();
resolve(url);
// if user types no, then use base url
} else if (url.toLowerCase() === 'no') {
url = URL;
resolve(url);
} else {
console.log(
'Please type in a valid URL or type "no" to use base url.'
)
requestSiteURL().then(resolve);
}
});
});
};
Edit: Adding an async/await version. Basically I think you don’t ever have to reject. I edited the above to not reject as well. Also I’m assuming URL is the default url (this conflicts with the global URL namespace, just for the record)
// request url from user in command prompt
const requestSiteURL = async function () {
const url = await new Promise(resolve => {
readline.question('Please type url: ', resolve)
})
if (validUrl.isUri(url)) {
readline.close()
return url
} else if (url.toLowerCase() === 'no') {
return URL
} else {
console.log('Please type in a valid URL or type "no" to use base url.')
return requestSiteURL()
}
}