DI_SO
DI_SO

Reputation: 853

TypeError: Object is undefined

In a code below:

var FilledObjectArray = function() {
    this.filledObject = {};
};

FilledObjectArray.prototype = {
        fill: function() {
            this.filledObject["one"] = 1;
        }
};

var SomeClass = function() {
    this.something = new FilledObjectArray();
};

SomeClass.prototype = {
    showContents: function() {
        this.something.fill();
        for (key in this.something) {
            $("#some-div").append(this.something[key]);
        }
    }   
};

$(document).ready(function() {

    var s = new SomeClass();

    $(".bla").each(function() {
        $(this).click(function() {
            s.showContents();
        });
    });

});

I'm getting this error in Firebug console:

TypeError: this.filledObject is undefined
this.filledObject["one"] = 1;

What I'm doing wrong here? From what I understand object is properly initialized and value assigning is correct. I'm testing this in Firefox 18.0.2 version and Chrome 25.

Upvotes: 3

Views: 10201

Answers (4)

DI_SO
DI_SO

Reputation: 853

I feel a bit dumb right now but here is the solution to this:

SomeClass.prototype = {
    showContents: function() {
        this.something.fill();
        for (key in this.something.filledObject) {
            if (this.something.filledObject.hasOwnProperty(key)) {
                $("#some-div").append(this.something.filledObject[key]);                
            }
        }
    }   
};

I was trying to access object itself (this.something) instead of object property (this.something.filledObject)

Upvotes: 0

Kevin Bowersox
Kevin Bowersox

Reputation: 94429

I found this issue with the existing code and have created a proposed solution, however I'm not exactly clear on your intent so it may be a little different than your needs, please modify as needed.

The Issue

The main issue stems from the FilledObjectArray object. This object's prototype is assigned a function fill and then assigned a property one of type int with a value of 1. So remember this object has two properties, one a function one an int.

So when you execute this code...

for (key in this.something) {
    $("#some-div").append(this.something[key]);  //Item 1
}

Two iterations of the loop occur, once for the function fill and once for the property one. The issue occurs on the iteration for the fill key, since this.something[key] is passed to the append(), which cann accept functions, causing jQuery to trigger the function. When this occurs, within the execution context of the fill function, this is assigned to #some-div, which does not have a filledObject property, causing the TypeError to be thrown. I have commented on some of this below:

var FilledObjectArray = function() {
    this.filledObject = {}; //Fill is an object
};

FilledObjectArray.prototype = {
        fill: function() {
            this.filledObject["one"] = 1;
        }
};

var SomeClass = function() {
    this.something = new FilledObjectArray();
};

SomeClass.prototype = {
    showContents: function() {
        this.something.fill();
        for (key in this.something) {
            $("#some-div").append(this.something[key]);  //The fill function is called here
        }
    }   
};

$(document).ready(function() {

    var s = new SomeClass();

    $(".bla").each(function() {
        $(this).click(function() {
            s.showContents();
        });
    });

});

Proposed Solution

var FilledObjectArray = function() {
    this.filledObject = [];
};

FilledObjectArray.prototype.fill = function(){
            console.log(this);
            this.filledObject[0] = 1;
};

var SomeClass = function() {
    this.something = new FilledObjectArray();
};

SomeClass.prototype = {
    showContents: function() {
        this.something.fill();
        for (var x = 0; x < this.something.filledObject.length; x++){
            $("#some-div").append(this.something.filledObject[x]);
        }
    }   
};

$(document).ready(function() {


    var s = new SomeClass();
    $(".bla").each(function() {

        $(this).click(function() {
            s.showContents();
        });
    });
});

Upvotes: 1

anhulife
anhulife

Reputation: 566

i think you looking for this:

for (key in this.something) {
  if(this.something.hasOwnProperty(key)){
    $("#some-div").append(JSON.stringify(this.something[key]));
  }
}

jsbin

you need use hasOwnProperty to iterate over the properties of an object without executing on inherit properties.

Upvotes: 0

Parv Sharma
Parv Sharma

Reputation: 12705

I think this should solve your problem

this.something.fill.call(this.something);

Upvotes: 1

Related Questions