0
var request = require('request-promise');
var cheerio = require("cheerio");
var fs = require('fs');


function sums() {
    function parseSites(urls, callback) {
        var parsedSites = [];
        var promiseList = urls.map(getPage);

    Promise.all(promiseList).then(function (data) {
        callback(data.map(parse));
    });

    return parsedSites;
}

//get data at url
function getPage(url) {

    return request.get(url);
}

//cheerio element grabber
function parse(body) {
    var $ = cheerio.load(body);
    return $(".stats > h3:nth-child(1) > span:nth-child(1)").html();
}

//array urls
parseSites([
    'url1' (120),
    'url2' (6.7k),
    'url3' (12k)
],

    function transy(data) {

        //Turn all array elements into integers
        //OLD ARRAY, NEW ARRAY
        var q = data;
        var z = [];

        for (i = 0; i < data.length; i++) {

            var x = q[i];
            var y = x.includes('.');

            if (y) {
                y = x.replace(/k/, "00");
                y = y.replace('.', "");
            }
            else {
                y = x.replace(/k/, "000");
            }
            z.push(y);
        }    
        console.log(z);
    });
}

sums();

Running the script in node makes 'console.log(z)' return:

['120', '6700', '12000']

I want to use this result and be able to parse it to my client as json/object/variable.

I tried the parse/stringify on the client and in the scope off my 'server.js' respectively to no avail. This is after using module.exports to 'require' it within the 'server.js' file.

I tried to change 'console.log(z)' to 'return z' and also within multiple places in the chain to no avail.

*quick note: the values behind the url within parenthesis (parseSites) are the values I get after scraping with cheerio and not the actual code. I use 'transy()' to make them in whole values for calculation purposes.

I googled it in many places and read (and still reading) node docs and tutorials, but it just seems I can't place my finger on what I do wrong.

I think it's because of the async runtime, but at this point I'm just guessing.

I used the below code in the end which does work in parsing it as a file and use it within a different way, but this is "cheating" in my context and not what I actually want it to do, which is keeping it in the program without active fs i/o.

var arr = z;
                var str = JSON.stringify(arr, null, 4);
                var filename = './public/output.js';
                var out = "var out = " + str + ";";

                fs.writeFile(filename, str, function (err) {
                    if (err) {
                        console.log(err);
                    } else {
                        console.log('File written!');
                    }
                });
  • You can't return the value directly from your function because it is obtained asynchronously and thus your function returns BEFORE the async values are available. You will need to communicate back the result with a promise or a callback. Since you are already using promises internally in the function, I'd suggest you return a promise from your function whose resolved value is an array of results. See the question yours was marked a dup of for more info on returning promises. – jfriend00 Jun 12 '17 at 14:00
  • Okay, thank you for your advice anyhow, I see what you mean and will read into the linked question. Should I delete my question, or is it custom to leave it here? – john zwarts Jun 12 '17 at 14:16
  • You can leave it here. It's marked as a duplicate so it is now closed. – jfriend00 Jun 12 '17 at 21:28

0 Answers0