user526929
user526929

Reputation: 93

cannot denodeify methods in node-ftp module

I am new to both node.js and promise style function call. By looking at an denodeify example at http://runnable.com/Ulatc0QnzUgUAAAK/adapting-node-js-with-q-for-promises, I am trying to denodeify the methods of the node.js node-ftp module as following:

var ftp = require('ftp');
var q = require('q');
var ftpClient = new ftp();
ftpClient.on('ready', function() {
    var ftpList = q.denodeify(ftpClient.list);
    ftpList().then(function(list) {
        console.log(list);
    }.then(null, function(err) {
        console.log(err);
    }).done(function() {
        ftpClient.end();
    });
});
ftpClient.connect();

However, when running that code with node, it shows the error "list error: TypeError: Object # has no method '_pasv'"

I am not sure what's wrong with that piece of code. Does anyone know what's wrong with that? Can you point me some way to debug/troubleshoot the cause of that error message?

Thanks.

Upvotes: 1

Views: 1255

Answers (2)

wayne
wayne

Reputation: 3410

you need to use q.nbind

q.nbind(ftpClient.list, ftpClient);

Upvotes: 1

thefourtheye
thefourtheye

Reputation: 239643

When you pass

ftpClient.list

to Q.denodefiy, you are getting the function object, list from the ftpClient object. It will be just a function and the relationship with the parent is lost. This is important because, the bound function list might be dependent on the ftpClient object. So, you must make sure that link is not broken.

Quoting from the Q.denodeify docs,

Note that if you have a method that uses the Node.js callback pattern, as opposed to just a function, you will need to bind its this value before passing it to denodeify, like so:

var Kitty = mongoose.model("Kitty");
var findKitties = Q.denodeify(Kitty.find.bind(Kitty));

The better strategy for methods would be to use Q.nbind, as shown below.

So, you can fix your code in two ways,

  1. Using Q.denodeify and Function.prototype.bind, like this

    var ftpList = q.denodeify(ftpClient.list.bind(ftpClient));
    
  2. Using Q.nbind, like this

    var ftpList = q.nbind(ftpClient.list, ftpClient);
    

Upvotes: 7

Related Questions