domwoe
domwoe

Reputation: 119

Node.js function returns undefined

I probably have some issues with the asyncness of Node.js.

rest.js

var Shred = require("shred");
var shred = new Shred();


module.exports = {
    Request: function (ressource,datacont) {
            var req = shred.get({
                    url: 'ip'+ressource,
                    headers: {
                Accept: 'application/json',

              },

              on: {
                // You can use response codes as events
                200: function(response) {
                  // Shred will automatically JSON-decode response bodies that have a
                  // JSON Content-Type
                  if (datacont === undefined){
                    return response.content.data;
                    //console.log(response.content.data);
                  }
                  else return response.content.data[datacont];
                },
                // Any other response means something's wrong
                response: function(response) {
                  return "Oh no!";
                }
              }
            });
    }
}

other.js

var rest = require('./rest.js');

console.log(rest.Request('/system'));

The problem ist if I call the request from the other.js I always get 'undefined'. If I uncomment the console.log in rest.js then the right response of the http request is written to the console. I think the problem is that the value is returned before the actual response of the request is there. Does anyone know how to fix that?

Best, dom

Upvotes: 1

Views: 5398

Answers (1)

loganfsmyth
loganfsmyth

Reputation: 161637

First off, it is useful to strip down the code you have.

Request: function (ressource, datacont) {
  var req = shred.get({
    // ...
    on: {
      // ...
    }
  });
}

Your Request function never returns anything at all, so when you call it and console.log the result, it will always print undefined. Your request handlers for the various status codes call return, but those returns are inside of the individual handler functions, not inside Request.

You are correct about the asynchronous nature of Node though. It is impossible for you to return the result of the request, because the request will still be in progress when your function returns. Basically when you run Request, you are starting the request, but it can finish at any time in the future. The way this is handled in JavaScript is with callback functions.

Request: function (ressource, datacont, callback) {
  var req = shred.get({
    // ...
    on: {
      200: function(response){
        callback(null, response);
      },
      response: function(response){
        callback(response, null);
      }
    }
  });
}

// Called like this:
var rest = require('./rest.js');
rest.Request('/system', undefined, function(err, data){
  console.log(err, data);
})

You pass a third argument to Request which is a function to call when the request has finished. The standard Node format for callbacks that can fail is function(err, data){ so in this case on success you pass null because there is no error, and you pass the response as the data. If there is any status code, then you can consider it an error or whatever you want.

Upvotes: 4

Related Questions