Noobie Nooberson
Noobie Nooberson

Reputation: 67

Getting "Function: Bound" when trying to call a method

I'm using the Sails.js MVC and I'm trying to setup a service so I can make a call to an Active Directory server and pass the data for a user back to my controller.

I'm using some internal company modules for this which connect to our servers and pass back a user array with all the data for a selected user.

If I do this by making a function directly in the API controller it works fine, but when doing it by calling through a function from a separate file, rather than returning an array of [Function: bound].

Code from controller (LabController.js):

var adGet = require('../services/adGet');
module.exports = {

test: function (req, res) {
    console.log(adGet.userData);
    res.view({
        user: adGet.userData
    });
}
}

Code from the service (adGet.js):

module.exports = {
userData: function (req, res) {
    var ad = require('active-directory');
    ad.setCredentials({
        user: 'username_removed',
        password: 'password_removed'
    });
    ad.getUser(req.session.sisso.idsid).then(function (user) {
        return (user);
    });
}
}

Any help is greatly appreciated.

Upvotes: 2

Views: 1661

Answers (1)

sgress454
sgress454

Reputation: 24958

There's a few issues here.

First, you're trying to use return in your userData service method to return data, but it's an asynchronous function so that return statement is sending the data anywhere. You need to pass in a callback function as an argument to userData that can be called when the data is ready (i.e. when the database query returns):

module.exports = {
  // note the new `cb` argument
  userData: function (req, res, cb) {
    var ad = require('active-directory');
    ad.setCredentials({
        user: 'username_removed',
        password: 'password_removed'
    });
    ad.getUser(req.session.sisso.idsid)
      .then(function (user) {
        // Still nice to use `return` to make sure nothing
        // gets executed after this statement, but it's the
        // callback function that actually gets the data.          
        // Note the `null` first argument, indicating no errors.
        return cb(null,user);
      })
      .catch(err) {
        return cb(err);
      });
  }
}

Second, you're sending the adGet.userData function to your view as a local variable, but you're not actually calling it to get the data. And since it's an asynchronous function, you won't be able to call it from your view. You need to call it from within the controller and send the result to the view:

var adGet = require('../services/adGet');
module.exports = {

  test: function (req, res) {
    // Call service function, passing callback function in as argument
    adGet.userData(req, res, function(err, user) {
      // Handle errors
      if (err) {return res.serverError(err);}
      // If all goes well, send user data to view
      return res.view({
        user: user
      });
    });
  }
}

Less importantly, you could refactor the userData method to not accept req and res as arguments--it's overkill. Save req and res for your controllers whenever possible. It would be better to have userData just expect userId and callback as arguments. Also, unless you've turned global services off using the config/globals.js file, you don't need to require the services file at the top of your controller; the adGet variable will be made available to you automatically.

Upvotes: 4

Related Questions