Is there a way to avoid using a “call” in Coffeescript?

I am writing a simple Twitter client to play with coffeescript. I have an object literal with some functions that call each other through callbacks.

somebject = foo: 'bar' authenticateAndGetTweets: -> console.log "Authorizing using oauth" oauth = ChromeExOAuth.initBackgroundPage(this.oauthdetails) oauth.authorize( this.afterLogin.call this ) afterLogin: -> this.getTweets(this.pollinterval) 

This code works just fine. Edit: in fact, this.afterlogin should be sent as a callback above, and not immediately started, as Trevor noted below.

If in authenticateAndGetTweets I deleted the “call” and just ran:

 oauth.authorize( this.afterLogin ) 

and do not use 'call', I get the following error:

 Uncaught TypeError: Object [object DOMWindow] has no method 'getTweets 

Which makes sense, since 'this' in afterLogin is tied to what triggered the callback, not the "some object" of my object literal.

I was wondering if there was any magic in Coffeescript that I could do instead of a “call”. I originally thought using '=>', but the code will give the same error as above if '=>' is used.

So, is there a way to avoid using a call? Or coffeescript does not eliminate the need? What did '=>' not work as I expected?

Thanks. I still like the coffee maker and want me to do everything right. "

+4
source share
3 answers

As matyr points out in his comments, the line

 oauth.authorize( this.afterLogin.call this ) 

does not call this.afterLogin to call this.afterLogin as a callback; instead it is equivalent

 oauth.authorize this.afterLogin() 

Assuming you want this.afterLogin to this.afterLogin used as an oauth.authorize , oauth.authorize 's answer gives the correct CoffeeScript idiom. An alternative approach supported by many modern JS environments, as Matir points out, would be to write

 oauth.authorize( this.afterLogin.bind this ) 

There are no CoffeeScript abbreviations here, in part because Function::bind not supported by all major browsers. You can also use the bind function from the library, for example Underscore.js :

 oauth.authorize( _.bind this.afterLogin, this ) 

Finally, if you defined someobject as a class, you could use => to define afterLogin so that it always binds to the instance, for example.

 class SomeClass foo: 'bar' authenticateAndGetTweets: -> console.log "Authorizing using oauth" oauth = ChromeExOAuth.initBackgroundPage(this.oauthdetails) oauth.authorize(this.afterLogin) afterLogin: => this.getTweets(this.pollinterval) someobject = new SomeClass 
+3
source

you can put a lambda in a function call like this:

 auth.authorize(=> @afterLogin()) 
+3
source

You must use calling or applying methods because they specify the scope of the function (the meaning of this). The error occurs because the default area is a window object.

0
source

All Articles