views:

49

answers:

3

This is the first time I've used JS objects and I'm confused as to why this property is always undefined:

function Rotator() {
    this.interval = 300;
    this.image = 0;
    this.images = undefined;
}

Rotator.prototype.Fetch = function(links) {
    console.log("Fetch called");
    this.images = links;
}

Rotator.prototype.Current = function() {
    if (this.images == undefined) {
        console.log("Error, images is undefined");
    }
    return this.images[this.image];
}

r = new Rotator;
$.getJSON("./data.php", function (data) {
    r.Fetch(data.images);
});

console.log(r.Current());

The error I get is:

Uncaught TypeError: Cannot read property '0' of undefined

The JSON returned is working fine, and fetch is marked as called in the console (when logged the data is fine as well). Why is Rotator.images always undefined?

Edit: Some console.log results:

  • Logging data.images in $.getJSON results in correct data.
  • Logging links in Fetch results in correct data.
  • Logging this.images in Fetch results in correct data.
  • Logging this.images in Current results in null.
A: 

You can't use undefined that way. Use null instead:

this.images = null;

and

if (this.images == null) {

Edit:

You also have to avoid using the images property if it's null:

Rotator.prototype.Current = function() {
  if (this.images == null) {
    console.log("Error, images is undefined");
    return null;
  }
  return this.images[this.image];
}
Guffa
You can use `undefined` in that way and it works on all major browsers (even IE6 supports it), the only problem is that in ECMAScript 3, the `undefined` global property doesn't exists, and its value is mutable...
CMS
I took that from a website but I've changed it anyway. I still have the same problem.
Ross
@Ross: The error message that you get is because you are trying to use the property even after that you have determined that it's not yet assigned. See my edit above.
Guffa
@CMS: You could use any unused variable as "undefined", as it's not defined, which works until it gets defined...
Guffa
+1  A: 

Because getting JSON is asynchronous, that's why the data is only available in the callback function.

$.getJSON("./data.php", function (data) { // callback function
    r.Fetch(data.images); // this will run when the data is available
});

console.log(r.Current()); // this will run immediately -> data.images is null

Everything that depends on the data should be placed in the callback function!

galambalazs
A: 

Will this get me purists on my neck or is it acceptable?

Rotator.prototype.Current = function() {
    if (this.images) return this.images[this.image];
    console.log("Error, images is undefined, null, empty or 0");
}
mplungjan
You're not solving the problem.
Adrian Godong
Oh, I can only answer if it solves the problem. My bad.
mplungjan