Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript this scoping problem

I'm loading a csv file and parsing it. and I want the resulting array to be a member of a certain object, but it ends up undefined, becuase I'm not using the "this" keyword correctly.

function SimPlayer(){

    this.dataset = new Array();
    var client = new XMLHttpRequest();
    var dset = this.dataset;

    function handler(){
        if(client.readyState == 4){
            if(client.status == 200){
                //file is done loading
                //split by lines
                dset = client.responseText.split("\n");
                for(var i=0; i<dset.length; i++){
                    //split each line by commas
                    dset[i] = dset[i].split(",");
                    //convert to ints
                    for(var j=0; j<dset[i].length; j++){
                        dset[i][j] = parseInt(dset[i][j]);
                    }
                }
                //dset is defined here, no problem. It contains the data from the csv file
                console.log(dset[0]);
            }
        }
    }
    client.onreadystatechange = handler;
    client.open("GET", "http://nathannifong.com/LayerCake/simdata/rec0_i0.csv");
    client.send();

    this.check = function(){
        //does not work because this.dataset will be empty.
        console.log(this.dataset[0])
    }
}

assume I create an instance of SimPlayer, and then call check later (after the csv file has had time to load)

foo = new SimPlayer();
//....time passes....
foo.check();

foo.check() causes

Uncaught TypeError: Cannot read property '0' of undefined

How can I fix my code so that in check(), this.dataset will contain the data from the csv file?

like image 829
Nathan Avatar asked Mar 19 '26 12:03

Nathan


2 Answers

You'll want to store a reference to the proper this binding:

var _this = this;
this.check = function(){
    //does not work because this.dataset will be empty.
    console.log(_this.dataset[0])
}
like image 183
ChaosPandion Avatar answered Mar 21 '26 02:03

ChaosPandion


As an alternative option you may consider the following example:

this.check = (function(thus){
    return function() {//does not work because this.dataset will be empty.
       console.log(thus.dataset[0])
    };
})(this);

PS: I haven't read the original post entirely, my example - only an alternative way for the answer. You may find such code in many JavaScript examples. You should understand using closures.

like image 20
Alexandr Avatar answered Mar 21 '26 02:03

Alexandr



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!