1

I'm a new in javascript. Faced with the following problem

var list = [];

initList(); // after this function I have some elements in `list`

var node = list[0]; //after the assignment firebug says `node` is undefined. `list[0]` is defined and contains object like {a:"value",b:"value1", ...}

What am I doing wrong? I've tried to declarate node like var node = {};. But It doesn't work too.

Here my initList function. Hopefully there will be those who will want to grasp it :))

function initList() {

    d3.json("./config.json", function (error, txt) {
        if (error) {
            console.debug(error)
        }
        txt.forEach(function (bop, i) {

            var nd = {};

            d3.json("./cgi-bin/getshmid.sh?key=" + (195951310 + bop.bop_id), function (error, shm) {
                if (error) {
                    console.debug(error)
                } else {
                    console.debug(bop, i)
                }


                d3.select("#tplace")
                    .append("h3")
                    .text("BOP's ID = " + bop.bop_id)

                var table = d3.select("#tplace")
                    .append("table")
                    .attr("id", "shmid_" + shm.id);

                var thead = table.append("tr")

                thead.append("td")
                    .text("Блоки детектирования, ID")
                thead.append("td")
                    .text("Текущее значение")
                thead.append("td")
                    .text("Предупредительная уставка")
                thead.append("td")
                    .text("Аварийная уставка")
                thead.append("td")
                    .text("Статус")
                thead.append("td")
                    .text("Превышение ПУ")
                thead.append("td")
                    .text("Превышение АУ")

                bop.BDs.forEach(function (bd, i) {
                    var tbody = table.append("tr")
                        .attr("class", "bd")
                    tbody.append("td")
                        .text(bd.index + 1)
                    tbody.append("td")
                        .attr("id", "val")
                    tbody.append("td")
                        .attr("id", "pz")
                        .attr("class", "edit " + (516 + i * 16) + "")
                    tbody.append("td")
                        .attr("id", "az")
                        .attr("class", "edit " + (518 + i * 16) + "")
                    tbody.append("td")
                        .attr("id", "status")
                    tbody.append("td")
                        .attr("id", "state_pz")
                    tbody.append("td")
                        .attr("id", "state_az")
                })

                nd = foo(shm.id);
                list.push(nd);
            })
        })
    })
};

function foo(id) {

    var node = {
        value: id,
        table: d3.select('#shmid_' + id),
        tr: d3.select('#shmid_' + id).selectAll(".bd"),
        bds: []
    };

    node.tr.each(function (d, i) {

        var bd = {};

        d3.select(this).selectAll("td").each(function (d, i) {

            switch (d3.select(this).attr("id")) {
                case 'val':
                    bd.val = d3.select(this);
                case 'pz':
                    bd.pz = d3.select(this);
                case 'az':
                    bd.az = d3.select(this);
                case 'status':
                    bd.status = d3.select(this);
                case 'state_pz':
                    bd.stpz = d3.select(this);
                case 'state_az':
                    bd.staz = d3.select(this);
            }
        });

        node.bds.push(bd);
    });

    return node;
};
naveen
  • 53,448
  • 46
  • 161
  • 251

2 Answers2

3

As per the question, the problem is that initList is an asynchronous function. So the array list won't be initialized.

var list = [];
initList(); //WARNING: asynchronous function!!!
var node = list[0]; 

You should start learning about JavaScript Promises


This is what happens with your code. The first line creates an array named list. The second line initializes the list via ajax calls. But before the callback happens, the third line gets executed giving you an error cos you are trying to fetch the first element of an un-populated array.
Update:

I have not tried this yet, but d3.promise plugin looks simple.

var promise = d3.promise.json('test.json')
promise.then(function (data) {
    // call successful
}, function (error) {
    //call failed
});
naveen
  • 53,448
  • 46
  • 161
  • 251
0

For better understanding i have added the below code.

function initList(){
 list.push(1);
 list.push(2);
}

var list = [];

initList(); // after this function I have some elements in `list`

var node = list[0]; //after the assignment firebug says `node` is undefined. `list[0]` is defined and contains object like {a:"value",b:"value1", ...}
console.log(node);

node has the value 1 now. I hope this helps you.

And also please check the scope the variable list in you code.

Kishore Sahasranaman
  • 4,013
  • 3
  • 24
  • 50