Question

I've tried (with success) to do an http request. I have some REST Api's, like graph.facebook.com as target. The functionality is the same. When i make an HTTP request with node.js as a simple program i can do it. Really i want to make a little module, and i have this code:

// file: facebook.js
var http = require('http');

var Facebook = (function() {
  function Facebook(access_token) {
    this.access_token = access_token;
  }

  Facebook.prototype.getObject = function(id) {
    var options;
    this.id = id;
    options = {
      host: 'graph.facebook.com',
      port: 80,
      path: '/' + id + '?access_token=' + this.access_token
    };
    return http.request(options, function(response) {
      response.on('data', function(d) {
        return JSON.parse(d);
      });
      request.end();
      return request.on('error', function(err) {
        return {
          error: 'An error ocurred.'
        };
      });
    });
  };

  return Facebook;

})();

module.exports = Facebook;

After, when i write a program i can do this:

var facebook = require('./facebook.js');
var fb = facebook('my_Access_token')
// Here's the problem:
var response = fb.getObject('My_facebook_profile_ID')

I get a response like

{ domain: null,
  _events: 
   { response: { [Function: g] listener: [Function] },
     socket: { [Function: g] listener: [Function] } },
....

When i must have something like

{
   "id": "MyIDNumer",    
   "first_name": "Orlando",
   "gender": "male",
   "last_name": "Sanchez",
   "link": "https://www.facebook.com/MyFacebookName",
   "locale": "es_LA",
   "name": "Orlando S\u00e1nchez",
   "username": "MyUsername"
}

What can i do?

Was it helpful?

Solution

The first thing you should do is rewrite the module to not use the same function name twice ('Facebook').

Secondly, there's no need for the closure, just export the constructor.

Thirdly, you are trying to return a value from an asynchronous callback. This particular issue is common with people coming from the synchronous world.

Assuming you wanted to do a GET request, here's your module refactored after the above and other things are fixed:

// file: facebook.js
var http = require('http');


function Facebook(access_token) {
  if (!(this instanceof Facebook))
    return new Facebook(access_token);
  this.access_token = access_token;
}

Facebook.prototype.getObject = function(id, cb) {
  var options;
  this.id = id;
  options = {
    host: 'graph.facebook.com',
    port: 80,
    path: '/' + id + '?access_token=' + this.access_token
  };
  http.get(options, function(res) {
    var buf = '',
        hadError = false;
    res.on('data', function(d) {
      buf += d;
    }).on('error', function(err) {
      hadError = true;
      cb(err);
    }).on('end', function() {
      if (hadError)
        return;
      var val;
      try {
        val = JSON.parse(buf);
      } catch (err) {
        return cb(err);
      }
      cb(null, val);
    });
  });
};

module.exports = Facebook;

Then use it like so:

var facebook = require('./facebook.js');
var fb = facebook('my_Access_token');
fb.getObject('My_facebook_profile_ID', function(err, response) {
  if (err) {
    // include better error handling here
    return console.log(err);
  }
  // use response here
  console.dir(response);
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top