Array returning Undefined because of asynchrony

Asked

Viewed 379 times

2

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

Access Trello information by 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 go through all these lines with the for, within the loop, assign each row to a variable x and call a function that aims to get the number of cards of that row. 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 vector numberCardsByList after the end of the search on the trello, 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’m aware it’s because of the asymchronism, but I can’t solve it.

2 answers

1


You have to have these orders chained (inside each other) to be able to assemble them asynchronously.

There’s a very good library for this who has a method async.map who 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);
    });
});

That way he runs the function findNumberCards for each element of the array you receive.

  • 1

    Perfect, thank you

0

The problem is that its global variable x is being overwritten before being used again in the return of the API to retrieve the cards.

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

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

Browser other questions tagged

You are not signed in. Login or sign up in order to post.