1

I am trying to access an object's member variables from inside a method that is passed as a callback which is fired during a filereader event.

I have whipped together the code below just to try and convey my point. It appears that 'this' becomes the filereader instead of the object at the point of call. Is there a way to have the finishLoading be able to access the objects variables?

I would like to make sure that the callbacks are tailored to the object, otherwise I would have just defined them as static functions outside the class.

function myClass(newName)
{
    this.name = newName;
    this.m_fileReader = new FileReader();

    this.finishedLoading = 
        function(param1)
        {
            alert(this.name);
        };

    this.m_fileReader.addEventListener('loadend',  
                                       this.callback_finishedLoading, 
                                       false);
}

var instance = new myClass('timmy');
var instance2 = new myClass('joe');
1

3 Answers 3

4

You need the .bind function:

this.m_fileReader.addEventListener('loadend',
    this.callback_finishedLoading.bind(this),
    false);

The .bind function will take the passed parameter, and call the original function with that parameter as its this instead of whatever value the browser tried to supply.

Alternatively, just create your own alias to this and wrap your call in an anonymous function:

var self = this;
this.m_fileReader.addEventListener('loadend', function(ev) { 
    self.callback_finishedLoading(ev)
}, false);

The latter is mostly what .bind does behind the scenes, but does have the advantage that it'll work on pre-ES5 browsers without a shim.

Sign up to request clarification or add additional context in comments.

1 Comment

Can't edit your answer because not enough characters, but you have what seem to be a couple copy/paste errors in the second example. The , in the callback, and the ) after the callback.
1

You can make your constructor implement the EventListener interface, like this:

function myClass(newName) {
    this.name = newName;
    this.m_fileReader = new FileReader();
    this.m_fileReader.addEventListener('loadend', this, false);
}

myClass.prototype.handleEvent = function(event) {
    return this[event.type] && this[event.type](event)
}

myClass.prototype.loadend = function(event) {
    alert(this.name);
};

var instance = new myClass('timmy');
var instance2 = new myClass('joe');

I renamed the finishedLoading to loadend, and put it on the .prototype of the constructor. Then I added a .handleEvent method to the .prototype.

Finally in the constructor, we don't pass a function at all. Instead just pass the this, which is your myClass instance.

I removed your param1 because it was unclear how that was to be used. If it needs to receive some value from other invocations, then you can create a separate finishedLoading method on the .prototype, and have the .loadend() method invoke it.

Comments

0

this is relative to the context. Every time you open a new block {} it changes to the current block context. Save this to another variable before calling the callback function.

Comments

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.