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() } }