Zia Ur Rehman
Zia Ur Rehman

Reputation: 1181

How do I refer to actual 'this' inside CoffeeScript fat-arrow callback?

The title says it all. When I use the fat-arrow in CoffeeScript, it stores this first before calling the function. For example:

class myClass
    constructor: ->
        element = $ "#id"
        element.click ->
            @myMethod(@value)
            return
        return

    myMethod: (c)->
        window.console.log(c)
        return

would yield

var myClass;

myClass = (function() {
  function myClass() {
    var element;
    element = $("#id");
    element.click(function() {
      this.myMethod(this.value);
    });
    return;
  }

  myClass.prototype.myMethod = function(c) {
    window.console.log(c);
  };

  return myClass;

})();

Now on line#8 of JavaScript, this.myMethod is wrong. In this scope, this refers to element instead of the class MyClass.

However, if on line#4 of CoffeeScript, I replace element.click -> by element.click => the line#8 in JavaScript will become _this.myMethod(_this.val) where this referring to myClass is stored in _this before calling the function. But _this.value is undefined and even if it were defined, the object I'm trying to access here is element (which is referred to by the actual this keyword in scope of this function).

How would access the actual this now?

Upvotes: 2

Views: 1172

Answers (1)

topr
topr

Reputation: 4612

You can achieve your goal in at least three ways. The 1st one would be:

class myClass
    constructor: ->
        element = $ "#id"
        element.click =>
            @myMethod(element.value)
            return
        return

    myMethod: (c) ->
        window.console.log(c)
        return

And the 2nd:

class myClass
    constructor: ->
        element = $ "#id"
        myMethodCallback = (c) => @myMethod(c)
        element.click ->
            myMethodCallback(@value)
            return
        return

    myMethod: (c) ->
        window.console.log(c)
        return

The 3rd one is as showed below. I'm not sure about jQuery API usage though, so better check on appropriate docs page.

class myClass
    constructor: ->
        element = $ "#id"
        element.click (event) =>
            @myMethod(event.target.value)
            return
        return

    myMethod: (c) ->
        window.console.log(c)
        return

I would prefer the 1st way as it seems to be more straightforward. This or the other but you need to decide 'which this' you would like to have in scope of the element.click callback. It's not possible to access two 'thises' at the same time.

By the way. All those return statements seems unnecessary. The shortest working solution would look like:

class myClass
    constructor: ->
        element = $ "#id"
        element.click => @myMethod(element.value)

    myMethod: (c) -> window.console.log(c)

Upvotes: 2

Related Questions