Welcome to Code Forum!

Join a community that supports you and your coding journey from day one. We strive to be a friendly, supportive community that empowers everyone to be better developers. By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!
  • Guest, before posting your code please take these rules into consideration:
    • It is required to use our BBCode feature to display your code. While within the editor click < / > or >_ and place your code within the BB Code prompt. This helps others with finding a solution by making it easier to read and easier to copy.
    • You can also use markdown to share your code. When using markdown your code will be automatically converted to BBCode. For help with markdown check out the markdown guide.
    • Don't share a wall of code. All we want is the problem area, the code related to your issue.

    GIF shows where to locate </> in the thread and or post editor toolbar.
    To learn more about how to use our BBCode feature, review our "How to post your code into threads" here.

    Thank you, Code Forum.

JavaScript fetch() constantly returns Promise object, should return Number or String

ppowell777

Well-Known Coder
I have no idea why this is happening, but every single time I run this simple function that fetches URL content and expect a String or Number, I get a Promise object, and I can't figure out why.

JavaScript:
/**
 * Options object based on https://stackoverflow.com/questions/41030425/disabling-cors-using-js-fetch
 */
async function checkUrl(url) {
    let text = '';
    try {
        const controller = new AbortController();
        const timeout = setTimeout(() => { controller.abort(); }, 5000);
        /*const options = {
          method: 'GET',
          mode: 'no-cors',
          signal: controller.signal
        };*/
        await fetch(url, { signal: controller.signal })
             .then((response) => {
                // BASED ON https://dmitripavlutin.com/timeout-fetch-request/ PUT clearTimeout() BEFORE THE return STATEMENT BLOCK
                clearTimeout(timeout);               
                /*if (response.status >= 200 && response.status < 400) {
                    //console.log(`GOOD response code = ${response.status}`);
                    return true;
                } else {
                    //console.log(`BAD response code = ${response.status}`);
                    return false;
                }*/
                return response.text();
             })
             .then((myText) => {
                text = myText;
             })
             .catch((e) => { return new TypeError(`Unable to obtain response code: ${e.message}`) });
    } catch (e) {
        //console.error(`Unable to run catchUrl(): ${e.message}`);
        return new TypeError(`Unable to run checkUrl(): ${e.message}`);
    }
    
    return text;
}

Can someone help me figure this out?
Thanks
 
Solution
I gave up on fetch() altogether and opted for jQuery.get() instead, and after trying to work with Promise objects more directly in the code, I finally got it to work, albeit being rather slow due to asynchronous functionality, but it works!

JavaScript:
function checkResourceUrls() {
    try {
        const waitingForTable = setInterval(() => {
            if (typeof document.getElementById('resources_table') !== 'undefined' && document.getElementById('resources_table') != null) {
                clearInterval(waitingForTable);
                const anchors = Array.from(document.getElementsByTagName('A'));
                checkResourceUrlLinks(anchors);
            }
        }, 100);
    } catch (e) {
        console.error(`Unable to run...
I have no idea why this is happening, but every single time I run this simple function that fetches URL content and expect a String or Number, I get a Promise object, and I can't figure out why.

JavaScript:
/**
 * Options object based on https://stackoverflow.com/questions/41030425/disabling-cors-using-js-fetch
 */
async function checkUrl(url) {
    let text = '';
    try {
        const controller = new AbortController();
        const timeout = setTimeout(() => { controller.abort(); }, 5000);
        /*const options = {
          method: 'GET',
          mode: 'no-cors',
          signal: controller.signal
        };*/
        await fetch(url, { signal: controller.signal })
             .then((response) => {
                // BASED ON https://dmitripavlutin.com/timeout-fetch-request/ PUT clearTimeout() BEFORE THE return STATEMENT BLOCK
                clearTimeout(timeout);              
                /*if (response.status >= 200 && response.status < 400) {
                    //console.log(`GOOD response code = ${response.status}`);
                    return true;
                } else {
                    //console.log(`BAD response code = ${response.status}`);
                    return false;
                }*/
                return response.text();
             })
             .then((myText) => {
                text = myText;
             })
             .catch((e) => { return new TypeError(`Unable to obtain response code: ${e.message}`) });
    } catch (e) {
        //console.error(`Unable to run catchUrl(): ${e.message}`);
        return new TypeError(`Unable to run checkUrl(): ${e.message}`);
    }
   
    return text;
}

Can someone help me figure this out?
Thanks
This is because you need to resolve the promise
 
Modified the code to handle the Promise object and I STILL get the Promise object back, not the URL's HTML string text

JavaScript:
/**
 * Options object based on https://stackoverflow.com/questions/41030425/disabling-cors-using-js-fetch
 */
async function checkUrl(url) {
    let text = '';
    try {
        const controller = new AbortController();
        const timeout = setTimeout(() => { controller.abort(); }, 5000);
        /*const options = {
          method: 'GET',
          mode: 'no-cors',
          signal: controller.signal
        };*/
        await fetch(url, { signal: controller.signal })
             .then((response) => {
                // BASED ON https://dmitripavlutin.com/timeout-fetch-request/ PUT clearTimeout() BEFORE THE return STATEMENT BLOCK
                clearTimeout(timeout);               
                /*if (response.status >= 200 && response.status < 400) {
                    //console.log(`GOOD response code = ${response.status}`);
                    return true;
                } else {
                    //console.log(`BAD response code = ${response.status}`);
                    return false;
                }*/
                if (response.ok && response.status == 200) {
                    return response.text();
                } else if (response.status >= 400) {
                    return Promise.reject(new TypeError(`Returned status of ${response.status}`));
                }
             })
             .then((myText) => {
                text = myText;
             })
             .catch((e) => { return new TypeError(`Unable to obtain response code: ${e.message}`) });
    } catch (e) {
        //console.error(`Unable to run catchUrl(): ${e.message}`);
        return new TypeError(`Unable to run checkUrl(): ${e.message}`);
    }
    
    return text;
}
 
I gave up on fetch() altogether and opted for jQuery.get() instead, and after trying to work with Promise objects more directly in the code, I finally got it to work, albeit being rather slow due to asynchronous functionality, but it works!

JavaScript:
function checkResourceUrls() {
    try {
        const waitingForTable = setInterval(() => {
            if (typeof document.getElementById('resources_table') !== 'undefined' && document.getElementById('resources_table') != null) {
                clearInterval(waitingForTable);
                const anchors = Array.from(document.getElementsByTagName('A'));
                checkResourceUrlLinks(anchors);
            }
        }, 100);
    } catch (e) {
        console.error(`Unable to run checkResourceUrls(): ${e.message}`);
    }
}

/**
 * This saved the day: https://stackoverflow.com/questions/42173350/synchronous-and-asynchronous-loops-in-javascript
 */
async function checkResourceUrlLinks(anchors) {
    try {
        let resourceId = '';
        let html = '';
        for (let anchor of anchors) {
            resourceId = (anchor.id.trim().startsWith('link_row_')) ? anchor.id.split('_')[2] : '';
            if (resourceId.trim().length > 0) {
                await new Promise(next => {
                    $.get(`${CHECKER_DEV_URL + '?url=' + encodeURIComponent(anchor.href)}`, (responseCode) => {
                        html = $(`#col1_${resourceId}`).html();
                        /**
                         * Bear in mind that the jQuery.get() asynchronous function will go tot he CMA's PHP side, to a
                         * specific URL, which will perform a PHP curl() based on the query string value being anchor.href here,
                         * perform a response status check, then return it as HTML consisting solely of the response code, which
                         * Javascript can interpret as being a Number
                         */
                        if (!isNaN(responseCode.trim()) && responseCode >= 200 && responseCode < 400) {
                            $(`#col1_${resourceId}`).html(`${html} ${GOOD_URL_INDICATOR}`);
                        } else if (!isNaN(responseCode.trim())) {
                            $(`#col1_${resourceId}`).html(`${html} ${BAD_URL_INDICATOR}`);
                        } else {
                            console.error(`Error attempting to verify "${anchor.href}" response code: ${responseCode}`);
                        }
                        
                        next();
                    });
                });
            }
        }
    } catch (e) {
        console.error(`Unable to run checkResourceUrls(anchor): ${e.message}`);
    }
}
 
Solution
I gave up on fetch() altogether and opted for jQuery.get() instead, and after trying to work with Promise objects more directly in the code, I finally got it to work, albeit being rather slow due to asynchronous functionality, but it works!

JavaScript:
function checkResourceUrls() {
    try {
        const waitingForTable = setInterval(() => {
            if (typeof document.getElementById('resources_table') !== 'undefined' && document.getElementById('resources_table') != null) {
                clearInterval(waitingForTable);
                const anchors = Array.from(document.getElementsByTagName('A'));
                checkResourceUrlLinks(anchors);
            }
        }, 100);
    } catch (e) {
        console.error(`Unable to run checkResourceUrls(): ${e.message}`);
    }
}

/**
 * This saved the day: https://stackoverflow.com/questions/42173350/synchronous-and-asynchronous-loops-in-javascript
 */
async function checkResourceUrlLinks(anchors) {
    try {
        let resourceId = '';
        let html = '';
        for (let anchor of anchors) {
            resourceId = (anchor.id.trim().startsWith('link_row_')) ? anchor.id.split('_')[2] : '';
            if (resourceId.trim().length > 0) {
                await new Promise(next => {
                    $.get(`${CHECKER_DEV_URL + '?url=' + encodeURIComponent(anchor.href)}`, (responseCode) => {
                        html = $(`#col1_${resourceId}`).html();
                        /**
                         * Bear in mind that the jQuery.get() asynchronous function will go tot he CMA's PHP side, to a
                         * specific URL, which will perform a PHP curl() based on the query string value being anchor.href here,
                         * perform a response status check, then return it as HTML consisting solely of the response code, which
                         * Javascript can interpret as being a Number
                         */
                        if (!isNaN(responseCode.trim()) && responseCode >= 200 && responseCode < 400) {
                            $(`#col1_${resourceId}`).html(`${html} ${GOOD_URL_INDICATOR}`);
                        } else if (!isNaN(responseCode.trim())) {
                            $(`#col1_${resourceId}`).html(`${html} ${BAD_URL_INDICATOR}`);
                        } else {
                            console.error(`Error attempting to verify "${anchor.href}" response code: ${responseCode}`);
                        }
                       
                        next();
                    });
                });
            }
        }
    } catch (e) {
        console.error(`Unable to run checkResourceUrls(anchor): ${e.message}`);
    }
}
Nice! Yeah async wil always bog down performance because you're waiting for those promises to resolve
 

Buy us a coffee!

Buy me a coffee.
Back
Top Bottom