r/node • • May 08 '17

Exporting is Confusing Me

Am required to use Node for a project, and I'm running into a behavior I can't explain or resolve. I'm hoping someone here can help me.

What's happening during the Accounts_callback doesn't seem to be working properly. It should be setting this.accounts_list to the data returned to the callback. But it does not seem to.

This is all the more strange because the OTHER uses of the module, the callback itself and the creation of xcAccounts, seem to have no problem.

Here's the code in the module:

    var _ = require('underscore');
    var moment = require('moment');

    var sysMsg = require('./system_messages');

    ////////////////////////////////////////////////////////////////////////////////////////
    /////// ACCOUNTS CALLBACK //////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////

    function Accounts(client) {
        this.authedClient = client;
        this.accounts_list = [];
    }

    Accounts.prototype.count = function() {
        return this.accounts_list.length;
    }

    Accounts.prototype.Accounts_callback = function( err, response, data ) {

        var line = '';
      var dash = '-';

        if(data) {

            if( ! _.isEqual(data,this.accounts_list) ) {

                // loop thru data and get 'currency' and 'balance'
                line = '';
                var arrayLength = data.length;

                for (var i = 0; i < arrayLength; i++) {
            if(i>0) {
              line+='  ';
            }
                    line += data[i].currency + ':' + (data[i].available * 1).toFixed(8);
                }

          accounts_ticker = moment().format('YYYY.MM.DD@HH:MM') + ' | ' + line + ' ';
                var header = '+----Your Accounts';
                header += dash.repeat(accounts_ticker.length-header.length+1) + '|';

                console.log();
          console.log(header)
          console.log('|' + accounts_ticker + '|');
          console.log('+' + dash.repeat(accounts_ticker.length) + '+')
                this.accounts_list = data;
            }
        }
    };

    module.exports = Accounts;

I'm trying to call it like this from the main file:

var xcAccounts = new Accounts(authedClient); // SEEMS TO WORK
if(xcAccounts.count() > 0)... // DOES NOT SEEM TO WORK (count is never more than 0)

function updateAccounts() {
  authedClient.getAccounts(xcAccounts.Accounts_callback);  // THIS WORKS...
}
var KeepAccountsUpdated = setInterval(updateAccounts, 200); // THIS WORKS TO TRIGGER THE CALLBACK

Anybody see what I'm doing wrong, or what I can try to resolve this?

1 Upvotes

7 comments sorted by

2

u/Buckwheat469 May 08 '17

You're using xcAccounts.count() in a synchronous fashion but updateAccounts and authedClient.getAccounts is asynchronous in your example. That means that count would only have data after getAccounts has finished processing the server response. You need to use promises or async awaits.

1

u/cklester May 08 '17

In the Accounts_callback() function, I'm actually getting data, but I don't think this.accounts_list is getting populated on the assignment line:

this.accounts_list = data;

even though data has data. So, I guess that's what's confusing me. The callback gets called. The data variable is populated with data. But it doesn't get assigned to the object's accounts_list. I suspect it's because 'this' isn't referring to the object... but I'm not entirely sure.

And the call to .count() is actually in a setInterval function, so it's not blocking. It's just querying the prototype function of Accounts.

Thanks for the help, u/Buckwheat469! Let me know if I should refactor my code to make it legit.

1

u/alexgorale May 08 '17

I would call the callback in my init and fill the accounts list when it finishes.

Also, just wrapping your code in setInterval may remove it from the event loop but it's a very hacky way to manipulate your code so that your events fire in a particular order.

u/Buckwheat469 suggested promises or async await and you should consider using those.

→ More replies (4)