1

I have a function which takes a url array and fetches the titles of those url's using npm package 'read-titles'. It successfully console.log the titles but does not push it into array.The array prints empty. The code is

function getTitleArray(addresses) {
    var titles = [];
    if (addresses.length > 1) {
        addresses.forEach((urls) => {

            console.log(urls.search('http'));
            if (urls.search('http://') == -1) {
                urls = 'http://' + urls;
            }

            readTitle(urls).then((title) => {
                titles.push(title);
                console.log(title);
            }, (err) => {
                res.status(400).send(err);
            });

        });
    }
    console.log('Titles are: ' + titles);
    return titles;
}
Bilalwcheema
  • 63
  • 2
  • 8
  • 3
    `readTitle` is asynchronous. Your console.log is called before the `readTitle` is finished. see also: https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call – Mark May 16 '18 at 13:49
  • 1
    Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Jared Smith May 16 '18 at 14:06

2 Answers2

1

As @Mark_M said, you have an asynchronous code, so you have to make a callback system to access to titles when all readTitle calls are over.

This is a recursive way you can use :

function getTitleArray(addresses, callback) {

    var titles = [];
    if (addresses.length > 1) {

        let syncCallReadTile = function (it = 0, callback) {
            let url = addresses[it];
            if (url.indexOf('http://') == -1) {
                url = 'http://' + url;
            }
            readTitle(url).then((title) => {
                titles.push(title);
                it++;
                if (it == addresses.length) {
                    callback(null, titles);
                }
                else {
                    syncCallReadTile(it, callback);
                }
            }, callback);
        };

        syncCallReadTile(0, callback);

    }
}

getTitleArray([], (err, titles) => {
    if (err) {
        res.status(400).send(err);
    }
    else {
        console.log("Title :", titles);
    }   
})
Sparw
  • 2,688
  • 1
  • 15
  • 34
0

Since readTitle is asynchronous, empty array is returned as response, Here modified the snippet using Javascript callback. Try this one.

function getTitleArray(addresses, callback) {
    var titles = [];
    if (addresses.length > 1) {
        addresses.forEach((urls, index) => {

            console.log(urls.search('http'));
            if (urls.search('http://') == -1) {
                urls = 'http://' + urls;
            }

            readTitle(urls).then((title) => {
                titles.push(title);
                console.log(title);
                if((addresses.length - 1) === index) {
                    callback(null, titles);
                }               
            }, (err) => {
                callback(err)
            });
        });
    }
}

getTitleArray([], (err, titles) => {
    if(err) {
        res.status(400).send(err);
    } else {
        console.log("Title :", titles);
    }   
})
Ashok JayaPrakash
  • 2,115
  • 1
  • 16
  • 22