Array returning Undefined because of asynchronism

2

I'm accessing the Trello API , but I came across the following problem:

Access the Trello information, obtaining the id of each existing queue, the code is as follows:

var x;  
var numberCardsByList = [];

trello.get("/1/boards/[idBoard]/lists/all", function(err, data) {
    if (err) throw err;
    console.log("Quantidade de Filas: " + data.length);

    for(var i=0; i<data.length; i++){
        x = data[i];
        findNumberCards(x);
    }
});

As you can see, after I get the size, I run through all those queues with for , inside the loop, assign each queue to a x variable, and call a function that aims to get the number cards of that queue. The code to get the number of cards is as follows:

trello.get("/1/lists/"+x.id+"/cards", function(err, dados){
    if(err) throw err;
    console.log("A fila com nome: " + x.name + " tem " + dados.length + " cards");
    numberCardsByList[x.name] = dados.length;
});

So far so good, however, when I try to access the numberCardsByList vector after the end of the trello search, it returns undefined:

var x;  
var numberCardsByList = [];

trello.get("/1/boards/[idBoard]/lists/all", function(err, data) {
    if (err) throw err;
    console.log("Quantidade de Filas: " + data.length);

    for(var i=0; i<data.length; i++){
        x = data[i];
        findNumberCards(x);
    }
});
console.log(numberCardsByList);

I am aware that it is because of asynchronism, but I can not solve it.

    
asked by anonymous 23.05.2016 / 14:31

2 answers

1

You have to have these requests chained (inside one another) so you can mount them asynchronously.

There's a very good library for this that has a method async.map that does what you want.

In your case you could apply like this:

var async = require('async');

function findNumberCards(fila, callback) {
    trello.get("/1/lists/" + fila.id + "/cards", callback);
}

trello.get("/1/boards/[idBoard]/lists/all", function(err, data) {
    if (err) throw err;
    console.log("Quantidade de Filas: " + data.length);
    async.map(data, findNumberCards, function(err, arr) {
        var numberCardsByList = {};
        arr.forEach(function(dados, i) {
            numberCardsByList[data[i].name] = dados.length;
        });
        // aqui tens o objeto numberCardsByList montado!
        console.log(numberCardsByList);
    });
});

In this way it runs the findNumberCards function for each element of the array it receives.

    
23.05.2016 / 16:04
0

The problem is that your global variable x is being overwritten before being used again in the API return to get the cards.

The simplest solution would be to pass the variable x.name as a parameter instead of the x itself, since it is the only value that is being used.

Another solution is to clone the x variable that is passed as a parameter, using, for example, the method extend of jQuery or the clone method of underscore.js.

    
23.05.2016 / 16:12