Fdo
Fdo

Reputation: 1093

Bluebird promisifyAll not creating entire set of Async functions

Maybe I'm not understanding the way Promise.promisifyAll works. I'm trying to promisify coinbase package.

Basically, the client's functions are promisified but the accounts returned by those functions don't appear to have the Async version: [TypeError: acc.getTransactionsAsync is not a function].

I've tried passing {multiArgs:true} as options to Promise.promisifyAll() as suggested in an answer to a similar question, but it didn't solve the problem. Any suggestion is appreciated.

Normal way of using the package (works):

var Client = require('coinbase').Client

var client = new Client({
  'apiKey': '<snip>',
  'apiSecret': '<snip>',
  'baseApiUri': 'https://api.sandbox.coinbase.com/v2/',
  'tokenUri': 'https://api.sandbox.coinbase.com/oauth/token'
});

//Callbacks
client.getAccounts({}, function(err, accounts) {
  accounts.forEach(function(acc) {
    acc.getTransactions(null, function(err, txns) {
      txns.forEach(function(txn) {
        console.log('txn: ' + txn.id);
      });
    });
  });
});

Promisified version not working (getTransactionsAsync is undefined, but the getAccountsAsync returns the accounts correctly):

var Promise = require('bluebird');
var Client = require('coinbase').Client;

var client = new Client({
  'apiKey': '<snip>',
  'apiSecret': '<snip>',
  'baseApiUri': 'https://api.sandbox.coinbase.com/v2/',
  'tokenUri': 'https://api.sandbox.coinbase.com/oauth/token'
});

Promise.promisifyAll(client);

//Promises
client.getAccountsAsync({}) //Works perfectly, returns the accounts
.then(function(accounts) {
  return Promise.map(accounts, function(acc) {
    return acc.getTransactionsAsync(null); //This function call is throwing the TypeError
  });
})
.then(function(transactions) {
  console.log('Transactions:');
  transactions.forEach(function(tx) {
    console.log(tx);
  });
})
.catch(function(err) {
  console.log(err);
});

EDIT:

Looking through the package I want to promisify, I realized that the functions I'm trying to call are from the model objects returned by the package. I think promisifyAll only parses the client functions, and the models are not being processed. I'm just not that well versed on how the parsing is made :(

This is the index.js (module exported)

var Account       = require('./lib/model/Account.js'),
    Address       = require('./lib/model/Address.js'),
    Buy           = require('./lib/model/Buy.js'),
    Checkout      = require('./lib/model/Checkout.js'),
    Client        = require('./lib/Client.js'),
    Deposit       = require('./lib/model/Deposit.js'),
    Merchant      = require('./lib/model/Merchant.js'),
    Notification  = require('./lib/model/Notification.js'),
    Order         = require('./lib/model/Order.js'),
    PaymentMethod = require('./lib/model/PaymentMethod.js'),
    Sell          = require('./lib/model/Sell.js'),
    Transaction   = require('./lib/model/Transaction.js'),
    User          = require('./lib/model/User.js'),
    Withdrawal    = require('./lib/model/Withdrawal.js');

var model = {
  'Account'       : Account,
  'Address'       : Address,
  'Buy'           : Buy,
  'Checkout'      : Checkout,
  'Deposit'       : Deposit,
  'Merchant'      : Merchant,
  'Notification'  : Notification,
  'Order'         : Order,
  'PaymentMethod' : PaymentMethod,
  'Sell'          : Sell,
  'Transaction'   : Transaction,
  'User'          : User,
  'Withdrawal'    : Withdrawal
};

module.exports = {
  'Client' : Client,
  'model'  : model
};

EDIT 2:

The Client requires it's own model modules, so Promise.promisifyAll should as expected with the object's properties without having the previous edit interfering. At this point I think there might be no other option that making my own Promises for all functions I will need that don't live directly under the client.

Upvotes: 0

Views: 646

Answers (2)

Bergi
Bergi

Reputation: 664599

I think promisifyAll only parses the client functions, and the models are not being processed.

Not exactly. This has nothing to do with how promisifyAll is looking through the methods and properties. Rather, you are explicitly passing only the client methods to be promisified:

var Client = require('coinbase').Client;
var client = new Client(…);
Promise.promisifyAll(client);

There's no link from client to the models. Rather try to call promisifyAll on the whole module, not only the Client class:

var Client = Promise.promisifyAll(require('coinbase')).Client;

or if that doesn't work, Call promisifyAll on both the Client class and the models collection of classes:

var coinbase = require('coinbase');
var Client = Promise.promisifyAll(coinbase.Client);
Promise.promisifyAll(coinbase.model);

Upvotes: 3

Fdo
Fdo

Reputation: 1093

So, instead of editing the question again I'm adding my temporary workaround (with a slightly different function call but that had the same problem of not having the Async function). This promisifies the model modules by it's own and I'll need to create them on demand whenever I need an promisified function on the non-promisified version of the models returned by the client.

It's not what I would like to do, since more memory allocation is needed for each model that I want to make a promisified function call. But I prefer this approach over creating new modules for grouping new Promise(...) functions.

If a better solution is suggested I'll still mark that as solved.

var Promise = require('bluebird');
var Client = require('coinbase').Client;
var cbModel = require('coinbase').model;

var client = new Client({
  'apiKey': '<snip>',
  'apiSecret': '<snip>',
  'baseApiUri': 'https://api.sandbox.coinbase.com/v2/',
  'tokenUri': 'https://api.sandbox.coinbase.com/oauth/token'
});

Promise.promisifyAll(client);
Promise.promisifyAll(cbModel);

//Promises
client.getAccountAsync('primary')
.then(function(account) {
  account = new cbModel.Account(client, account);
  return account.getTransactionsAsync(null);
})
.then(function(transactions) {
  console.log('Transactions:');
  transactions.forEach(function(tx) {
    console.log(tx.id);
  });
})
.catch(function(err) {
  console.log(err);
});

Upvotes: 0

Related Questions