0

I literally just started nodeJS and have been meddling with it for the past 8 hours. I have done J2EE and .NET before and wanted to get into NodeJS too.

I faced a problem while trying to get the response from the Data.js file. I can successfully stringify the data but for some reason I can't return it back. It ends up being null or and empty string(its default value) in the index.js router. I have explained with comments in the Data.js code below.

Thank you in advance and please tell me how I can improve my code :) I still have lots of concepts to learn

index.js

var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
var Data = require('../public/javascripts/Data');
var responseString = Data.test;

  res.render('index', { d: responseString });
  console.log(responseString)
});

module.exports = router;

Data.js

var request = require('request'),
cheerio = require('cheerio'),
responseTitles = [],
responseUrls = [],
responseJSONArray = [],
responseTotalNumber = 0,
responseString = "";


function getData(){
request('URL',function(err,response,body){
    console.log("requesting..")
    if(!err && response.statusCode == 200){
        console.log("success..")
        var $ = cheerio.load(body);
        var data = [];
        data = $('span.titletext');
        data.each(function(i){
            responseTitles.push(data[i].children[0].data);
            responseUrls.push(data[i].parent.attribs.url);
            responseTotalNumber = i;

            responseJSONArray.push([{index: i, Title: data[i].children[0].data, url: data[i].parent.attribs.url}])
        });
        responseString = JSON.stringify(responseJSONArray);
        //At this point, responseString has all the data but
        //if I put the return here, it doesn't return anything
    }
  });
 //At this point responseString returns "". And so it returns an empty string
 return responseString;
}


module.exports= {
   test: getData()
};
ExPlOiD
  • 153
  • 2
  • 13

1 Answers1

2

Your getData function is asynchronously calling request, then immediately returning the value of responseString, which will always be ''.

Think about the code:

module.exports= {
    test: getData()
};

What is happening here? You are

  1. Immediately executing your getData function, which:
    • executes request, and
    • returns ''
  2. Exporting your module with a single field test containing this result ('').

So you are essentially doing this:

module.exports = {
    test: ''
};

Which I assume is not your intention. You probably want something closer to this:

module.exports = {
    test: getData
};

Excluding the parens means you are returning the function itself rather than the result of calling the function.

As you are working asynchronously you likely want to include a callback argument or return a promise from your getData function in order to access the results of the request. Perhaps something like this:

Data.js:

function getData (cb) {
    request('URL', function (err, response, body) {

       ...

       responseString = JSON.stringify(responseJSONArray);
       cb(responseString);
    });
}

module.exports = {
    test: getData
};

and then using it like this:

Index.js

var data = require('../public/javascripts/Data');
router.get('/', function (req, res, next) {
    data.test(function (responseString) {
        res.render('index', { d: responseString });
    });
});
Alex McMillan
  • 17,096
  • 12
  • 55
  • 88
  • Well that makes sense, but how do I go about solving it ? I'm sorry, even thought I have worked with async calls before, in .NET, I'm still not getting the concept here in NodeJS. – ExPlOiD Mar 06 '16 at 23:04
  • Is it possible to return just the responseString rather than actually the whole function ? The responseString variable did have all the data at the point after I stringified responseJSONArray variable as stated in the comments. But seems like it since the method is async, it didn't wait for the response – ExPlOiD Mar 06 '16 at 23:14
  • @ExPlOiD have a look at the example I've thrown up for you. It's not possible to return the `resultString` itself - you have to asynchronously access it after the call to `request` has completed. – Alex McMillan Mar 07 '16 at 00:55
  • Alright thanks a lot ! I've got lots to learn and this only the start ! :) – ExPlOiD Mar 07 '16 at 00:58