ltsstar
ltsstar

Reputation: 892

javascript this returns unknown property

I just wrote that piece of code and get an error at the alert part telling me, that this.words is not definded. I guess the jquery part changes the "this" value, because at where the comment is, I can access the array.

Now I stuck, because I don't want to make the words property global (what makes it run). So I want to ask you for a way to fix the problem while keeping in "OOP" style.

function game()
{
    this.difficulty = 0;
    this.mode = 0;
    this.words = new Array();

    this.loadWords = function()
    {
        //request word pool
        $.ajax({
            type:"GET",
            url:"word.php",
            data:{mode:this.mode, difficulty:this.difficulty}
        }).done(function(html) {
            alert(this.words.length);
        });
    }
}

Upvotes: 2

Views: 371

Answers (5)

James Black
James Black

Reputation: 41858

You can look at

http://javascript.crockford.com/private.html

for more ideas on private, protected and public in javascript, but here is a solution:

Untested code

function game() {
    var difficulty = 0;
    var mode = 0;
    var words = [];
    this.loadWords = function()
    {
        //request word pool
        $.ajax({
            type:"GET",
            url:"word.php",
            data:{mode:this.mode, difficulty:this.difficulty}
        }).done(function(html) {
            alert(this.words.length);
        });
    }
}

You would want a getter for words also, but basically there is one way to initialize it, by calling the function and any other access is through the getter.

Untested code

    function game() {         var difficulty = 0;         var mode = 0;         var words = []; var that = this;         this.loadWords = function()         {             //request word pool             $.ajax({                 type:"GET",                 url:"word.php",                 data:{mode:that.mode, difficulty:that.difficulty}             }).done(function(html) {                 alert(this.words.length);             });         }     }

I added a that variable and set it to this, to help enclose that value, but in the ajax call it may be enough to call the mode variable directly, but it may be needed to use that. Also, the this before the function may be an issue, not certain, I would need to use a debugger to see what is actually happening and see what to use actually.

I had missed the this inside the .ajax call, which was the problem initially.

Upvotes: 0

Esailija
Esailija

Reputation: 140228

function Game()
{
    this.difficulty = 0;
    this.mode = 0;
    this.words = new Array();
    this.wordsLoaded = $.proxy(this.wordsLoaded, this);
}

var method = Game.prototype;

method.loadWords = function() {

    $.ajax({
        type:"GET",
        url:"word.php",
        data:{mode:this.mode, difficulty:this.difficulty},
        success: this.wordsLoaded
    });

};

method.wordsLoaded = function() {
    alert( this.words.length );
};

Upvotes: 3

jackwanders
jackwanders

Reputation: 16040

This appears to be a scoping issue. this no longer refers to the game object within the .done function. Try

this.loadWords = function()
{
    var that = this;
    //request word pool
    $.ajax({
        type:"GET",
        url:"word.php",
        data:{mode:this.mode, difficulty:this.difficulty}
    }).done(function(html) {
        alert(that.words.length);
    });
}

Upvotes: 3

Mark Pieszak - Trilon.io
Mark Pieszak - Trilon.io

Reputation: 67131

Save the game function internally by doing something like:

var _self = game;

That way you do _self.difficulty, _self.words.length, etc... and they will be able to access it.

Upvotes: 1

jfriend00
jfriend00

Reputation: 707736

The value of this is changed in your `done() handler so it is no longer your object. You can fix it by saving away the copy of this into another variable like this:

function game()
{
    this.difficulty = 0;
    this.mode = 0;
    this.words = new Array();

    this.loadWords = function()
    {
        var self = this;
        //request word pool
        $.ajax({
            type:"GET",
            url:"word.php",
            data:{mode:this.mode, difficulty:this.difficulty}
        }).done(function(html) {
            alert(self.words.length);
        });
    }
}

Upvotes: 2

Related Questions