Search code examples
javascriptmethodscallbackthis

When I use a method as a callback, it seems to lose access to `this`. Why?


I'm using express in Node to create a simple web app. The code looks like this:

var get_stuff = function (callback) {
    another.getter(args, function (err, data) {
        if (err) throw err;

        data = do_stuff_to(data);

        callback(data);
    });
};

app.get('/endpoint', function (req, res) {
    get_stuff(res.send);
});

When I run this, though, I get this error: TypeError: Cannot read property 'method' of undefined at res.send. The express code that's breaking starts like this:

res.send = function (body) {
    var req = this.req;
    var head = 'HEAD' == req.method;

It seems to me that the way I've constructed the callbacks is losing this in the send method. But I'm not sure how to fix it. Any tips? Thanks!


Solution

  • Call .bind:

    get_stuff(res.send.bind(res));
    

    and have a look at the MDN documentation about this to get an idea how it works. The value of this is determined by how the function is called. Calling it "normally" (what probably happens with the callback), like

    func();
    

    will set this to the global object. Only if a function is called as an object method (or if this is explicitly set with .bind, .apply or .call are used), this refers to the object:

    obj.fun(); // `this` refers to `obj` inside the function
    

    .bind allows you to specify the this value without calling the function. It simply returns a new function, similar to

    function bind(func, this_obj) {
        return function() {
            func.apply(this_obj, arguments);
        };
    }