1

I have an async call that, when it completes, I want to set a property on the parent.

Take the following class, cat:

var cat = function(){
   this.isLoaded = false;
   this.image = new Image();
   this.image.onload = function(){
     //how can I set the isLoaded variable above from here??
   }
   this.image.src = "...";
}

I want to be able to do:

var myCat = new cat();
if(myCat.isLoaded)
....

I cant seem to figure out how to set the isLoaded property above from within the onload. I can access it by just doing 'isLoaded' but I think I am accessing it by value, not reference, and thus cant change it.

This seems like an easy solution, I guess I lack the deeper understanding.

Thanks!

2 Answers 2

3

Inside the onload callback, isLoaded is undefined, and if you set it, it will be window.isLoaded (essentially a global).

The callback's this too points to an img element, not its parent function. I made a that variable that points to the outer function's this. Functions in functions have access to their outer function's scope in JavaScript.

var Cat = function(){
   this.isLoaded = false;
   this.image = new Image();
   var that = this;
   this.image.onload = function(){
     that.isLoaded = true;
   }
   this.image.src = "http://www.gravatar.com/avatar/5e28492984e3056904e295c43337655f?s=32&d=identicon&r=PG";
}

var c = new Cat();

console.log(c.isLoaded); // false

setTimeout(function() { console.log(c.isLoaded) }, 1500); // true

jsFiddle.

Of course, the setTimeout() is used for this example only. If you are loading an image, you should rely on callbacks, because the only other way to determine if the image has loaded is by polling - not a very good interface.

You should provide a place to pass in a callback, so you can do...

var c = new Cat(function() {
   // Image loaded, proceed.
});
Sign up to request clarification or add additional context in comments.

2 Comments

ok so to make sure I understand this correctly - a function in a function has access to the outer function/objects 'local/private' variables (declared via var a) and not the objects attached to the function itself? (via this.a)
@Steve It has access to its parent scope, but the value of this changes, so you need a reference.
1

Like @alex said you need to reference your cat object.

But if your internet connection is poor setTimeout won't help you much. Here is an example to use callback functionality instead of setTimeout

var cat = function (callback) {
   var this_cat = this;
   this.isLoaded = false;
   this.image = new Image();
   this.image.onload = function(){
     //how can I set the isLoaded variable above from here??
    this_cat.isLoaded = true;
    if (callback instanceof Function) { //@alex tip: callback instanceof Function is more accurate. Chrome reports the regex literal is a function.
        callback();
    }
   }
   this.image.src = "/images/stand_logo.png";
}

var myCat = new cat(function () {
    console.log('cat loaded');
});

2 Comments

I used setTimeout() only for this example.
To determine if a callback is a function, callback instanceof Function is more accurate. jsFiddle -> Chrome reports the regex literal is a function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.