2

I have the following code and I'm basically making a request to my api to retrieve JSON data and exporting this custom module.

The problem is that with var data = require('./lib/data.js'); alone, data doesn't really have the data I expected to have.

If it was a physical JSON file sitting in the project, I could do var data = require('./data.json'); but I don't work with this kind of static data.

What's wrong here?

data.js (my custom module to get JSON data)

module.exports = function() {

    var request = require("request")
    var url = "http://sheetsu.com/apis/94dc0db4"

    request({
        url: url,
        json: true
    }, function (error, response, body) {

        if (!error && response.statusCode === 200) {
            console.log(body)
        }
    })

}

index.js

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

var data = require('./lib/data.js');

router.get('/', function(req, res, next) {
  res.render('index', { 
    title: 'Express' 
    data: data
  });
});

module.exports = router;
Seong Lee
  • 10,314
  • 25
  • 68
  • 106

1 Answers1

1

There are a couple of things to consider here:

  1. Your request to the server is Asynchronous
  2. You're not actually returning the data to the module.exports
  3. Some basic syntax errors in your code

Try this:

data.js

module.exports = function(callback) {

    var request = require("request")
    var url = "http://sheetsu.com/apis/94dc0db4"

    request({ url: url, json: true }, function (error, response, body) {
        if (!error && response.statusCode === 200) {
            callback( body );
        }
    });
}

index.js

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

var data = require('./lib/data.js');

data( function(data) {

    router.get('/', function(req, res, next) {

        res.render('index', { title: 'Express', data: data });

    });
});

module.exports = router;

In a bit more detail; the request to get your JSON data will not be synchronous. That means that it can take any amount of time to respond back with the data, so it allows your program to finish its current thread. This means that when your index.js file is receiving the data.js module, the data may not have arrived yet. You can read more about asynchronous vs synchronous here.

How do we get around this problem? We pass the method a callback function to execute when it is finished.

When we execute the module...

data( function(data) { ...

...We're passing it a function to run when it receives the data from the server. If there is no error from the server and the statusCode is OK...

if (!error && response.statusCode === 200) { ...

... Then we call the callback function that was passed, passing the body (or data, if you like) as an argument...

callback( body );

...We can then use this in our index.js...

res.render('index', { title: 'Express', data: data });
Community
  • 1
  • 1
shennan
  • 10,798
  • 5
  • 44
  • 79