Search code examples
node.jsasync-awaitftpnode-promisify

Can't Promisify node-ftp Function


I am using the node-ftp library and I would like to promisify certain methods (list() and get()).

I am aware that there are promise-based wrappers, but I need to return the readable stream (and not write to a local file) and node-ftp allows this.

the get() method appears to follow the right pattern for promisification, but I cannot get it to work:

list([< string >path, ][< boolean >useCompression, ]< function >callback)

The non-promisified code works as expected

// THIS WORKS

var Client = require('ftp');

var c = new Client();

c.on('ready', function () {
  c.list('/mypath', function (err, data) {
    console.log(data)
  })
});
c.connect()

.. the promisified code does not:

// THIS DOES NOT WORK

var Client = require('ftp');
var { promisify } = require('util');

var c = new Client();

var ftp_list = promisify(c.list)

c.on('ready', function () {

  ftp_list('/mypath')
      .then(data => {
        console.log(data)
      })      
      .catch((err) => {
        console.log('Error', err);
      });    

});
c.connect()

returns error: TypeError: this._pasv is not a function

The presence of this. in the error makes me think this is an arrow function issue, but using a normal function did not work either.

Can this node-ftp function (and likewise c.get()) be promisified this way? Or am I missing something?


Solution

  • When you pass c.list to promisify, you want it to keep the calling context of c (so that the this used by the implementation of .list has the _pasv property), so use .bind:

    var ftp_list = promisify(c.list.bind(c))