Pobe Pobe - 2 months ago 8
Javascript Question

http.get or http.request callback only shows within shell - node.js

New to node and trying not to do any callback hell.

I have two files

routes.js

fetch.js


//routes.js
var fetchController = require("../lib/mtl_fetcher/fetcher_controller");
var express = require('express');
var router = express.Router();

router.get('/', function(req, res, next) {
res.send(fetchController.getAllTransgressor(function(results) {
return results.end();
}))
});

module.exports = router;


and

//fetch.js
var http = require('http');
var config = require('./config')
var Iconv = require('iconv').Iconv

module.exports.getAllTransgressor = function(callback) {

var req = http.get(config.urlOptions.host, function (response) {
var bufferChunk = [];
var str

if(response.statusCode == 200) {

response.on('data', function(chunk) {
bufferChunk.push(chunk);
})

response.on('end', function(callback) {
var iconv = Iconv('latin1', 'UTF-8');
str = iconv.convert(Buffer.concat(bufferChunk)).toString();
console.log(str)
});
} else {
console.log("handle this")
}
});

req.on("error", function(err) {
callback(err);
});

callback(req)
}


So the goal is to fetch and then show what has been fetch to the screen. The ressource is XML base.

Doing all of this in one block (routes.js) works, but when I try to refactor and set up some modularity my
str
just shows in shell stdout.

Using
req.end()
does not send the content back.

Answer

Firstly, you need to send inside the callback, where the result is actually available, as you can't return from an asynchronous function

router.get('/', function(req, res, next) {
    fetchController.getAllTransgressor(function(error, results) { 
        if ( error ) {
            // handle errors
        } else {
            res.send(results);
        }
    });
});

The same goes for the callback function, it has to be called when the data is available, after the request and parsing

module.exports.getAllTransgressor = function(callback) {

  var req = http.get(config.urlOptions.host, function(response) {
    var bufferChunk = [];

    if (response.statusCode == 200) {

      response.on('data', function(chunk) {
        bufferChunk.push(chunk);
      });

      response.on('end', function() {
        var iconv = Iconv('latin1', 'UTF-8');
        var str   = iconv.convert(Buffer.concat(bufferChunk)).toString();

        callback(null, str); // here, stuff is available
      });

    } else {
      callback('Did not return 200', err);
    }
  });

  req.on("error", function(err) {
    callback(err, null);
  });

}