I want the javascript code to be
someFunction(42, function onSuccess() {}, function onFailure() {})
Notice that while defining onSuccess and onFailure, I want to name them (not because it's necessary, but because it documents the code). However, I can't get coffeescript to generate this code.
For anonymous function passing I can do
someFunction(42,
->
// onsuccess code
->
// onfailure code
)
But when I tried to give names to those functions, it didn't translated as expected to Javascript
someFunction(42,
onSuccess : ->
// onsuccess code
onFailure : ->
// onfailure code
)
translates to
someFunction(42, { onSuccess : function () {}, onFailure : function () {} })
Another try
someFunction(42,
onSuccess ->
// onsuccess code
onFailure ->
// onfailure code
)
translates to
someFunction(42, onSuccess(function () {}), onFailure(function () {}))
How do I do this?
does this work?
someFunction 42, (onSuccess = -> ), onFailure = ->
http://jsfiddle.net/keith_nicholas/Qdzph/
generates..
somefunction(42, (onSuccess = function() {}), onFailure = function() {});
also, this might be of interest http://kangax.github.com/nfe/
and, in the coffeescript faq, it talks about why you can't generate named functions :-
https://github.com/jashkenas/coffee-script/wiki/FAQ
The only way to create named functions in CoffeeScript is to use class:
someFunction 42,
class onSuccess
constructor: ->
class onFailure
constructor: ->
Related
Happened to me many times that forgettin to add ()=> ruined my code and contributed to weird bugs.
I mean this:
funtion(){
...
}
ElevatedButton(
onPressed: ()=> function()
Sometimes I am still not sure when I should use:
function or function() or ()=> function()
Can someone explain how to choose so code works properly? Thank you in advance
Given:
R f() {
...
}
f is a reference to a Function object that, when invoked, returns an object of type R.
f() actually invokes the function f. The result of the function call is an object of type R.
() => f() is equivalent to () { return f(); }. It creates a new Function object that, when invoked, then invokes f and returns its return value. It's the same thing as #1 (a Function object that returns an R when invoked) but in a more convoluted form. That is, your code:
onPressed: () => function()
essentially is:
onPressed: function
Happened to me many times that [forgetting] to add ()=> ruined my code and contributed to weird bugs.
That should be rare. If that's happening, you probably aren't using strong typing and are using dynamic types throughout your code. If you specify return types, argument types, variable types, etc. and use Dart analyzer, you usually should be able to catch misuses early without needing to run your code.
If your function and callback have the same parameter types you can simply call the function name alone. Like,
function() {
...
}
ElevatedButton(
onPressed: function,
);
If your function and the callback have the different paremter and you have to call a function alone. You can call the method by using lambda expression like below,
function() {
...
}
GestureDetector(
onTap:(details) => function(),
);
It's like
function() {
...
}
GestureDetector(
onTap:(details) {
function();
},
);
I have come across this construct a few times.
Example 1:
_ = require 'underscore'
class Controller extends App
_doSomething: _.throttle (event) ->
$div = $(event.target).closest 'div'
...
My Question:
I have trouble understanding why this construct is valid.
Normally a class function definition goes like:
_doSomething: (event) ->
$div = $(event.target).closest 'div'
...
, 500
So how can _.throttle sit in between : and (event) the function parameter?
If _.throttle is supposed to act as an wrapper, shouldn't it be written as
_doSomething = _.throttle( (event) -> # an anonymous function that takes event as parameter
$div = $(event.target).closest 'div'
...
, 500
Things might be clearer if we add the optional parentheses:
class Controller extends App
_doSomething: _.throttle( (event) ->
$div = $(event.target).closest 'div'
...
)
Now we see that _.throttle is function call and it is being given an anonymous function as its single argument. We can break it down a bit more to further clarify what's going on:
f = (event) ->
$div = $(event.target).closest('div')
...
throttled_function = _.throttle(f)
class Controller extends App
_doSomething: throttled_function
_.throttle returns a function so the code you're looking at just just a complicated version of:
class Controller extends App
_doSomething: some_function
which is nothing special. Keep in mind that you can use anonymous functions when building a class's methods but named functions or other expressions which evaluate to functions serve just as well; the syntax is really:
name: expr
where expr is some expression and f(x) (or _.throttle(some_anonymous_function)) is an expression.
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?
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)
I have a "class" in coffee script whose instance variables I want to initialize with instance methods that return a value via a callback, but it doesn't work as I had hoped:
EventEmitter = require('events').EventEmitter
class MyClass extends EventEmitter
constructor: ->
#datamember: setDatamember()
setDatamember: ->
someFunction (response) ->
#datamember = response
#emit 'init'
getDatamember: ->
return #datamember
----
myObj = new MyClass
myObj.on 'init', ->
console.log myObj.getDatamember
The result I get suggests that "this" in setDatamember is referring to something different from what "this" refers to in the object instance. If I explicitly call myObj.setDatamember, I get the expected result, but is there any way to call on a set method -- specifically one that sets the data member via a callback -- in the constructor? I've looked through the docs, as well as various other sources of coffeescript info (e.g. this one), and I haven't found anything that touches upon this.
Try using a fat arrow for the anonymous function:
setDatamember: ->
someFunction (response) =>
#datamember = response
#emit 'init'
Also, you'll need to call the correct function in the constructor:
constructor: ->
#setDatamember()
In general, avoid fat arrows on methods - the way Coffee-Script implements this does some bad things to memory usage. Also, it will rarely be necessary.
However, anonymous functions that refer to this will almost always need fat arrows. this is not held in closure like normal variables, and will only be set by binding (Function.prototype.bind) or by calling it as an object method (obj.myMethod() will set this to obj in myMethod).
Try using fat arrows on everything except the constructor:
class MyClass
constructor: ->
#setDatamember()
setDatamember: =>
someFunction (response) =>
#datamember = response
getDatamember: =>
return #datamember
However, you also look to have someFunction in there as an asynchronous function, so you'll never be able to just do
mc = new MyClass
console.log mc.datamember
Because that doesn't wait for someFunction to return before accessing mc.datamember.
I started writing coffeescript last week, as I am programming a new Play20 site where coffeescript is the standard. I want to update a getData function in my class every 5 minutes, but the setInterval function does not bind to my class. Only the first time it calls getData, because the 'this' object is still reachable, as the setUpdateInterval() function is called from within the constructor.
But after the first call, the setInterval does not have any connection anymore with the Widget instance, and does not know what the this.getData() function is (and how to reach it).
Does someone know how to do it?
Here is my code:
class Widget
constructor: (#name) ->
this.setUpdateInterval()
getData: ->
console.log "get Data by Ajax"
setUpdateInterval: (widget) ->
setInterval( this.getData(), 3000000 )
Now here some Javascript magic is required. Reference
class Widget
constructor: (#name) ->
this.setUpdateInterval()
getData: ->
console.log "get Data by Ajax"
setUpdateInterval: (widget) ->
callback = #getData.bind(this)
setInterval( callback, 3000000 )
This will work in almost all browsers (guess which one not), so the
function will have to be bound differently. Some coffeescript magic:
callback = => #getData
The problem is that you are executing the function, instead of passing a reference to it.
Now, it sounds like you need to also keep the scope of the instance. do and => can help with that.
setUpdateInterval: (widget) ->
setInterval (do =>
#getData), 3000000
true
compiles to
Widget.prototype.setUpdateInterval = function(widget) {
var _this = this;
setInterval((function() {
return _this.getData;
})(), 3000000);
return true;
};
you will note the code executes a self invoking function, which return a function, that creates a closure around this, locking it into the scope of the callback (as _this)
Also note that you don't need to pass widget to the method (you aren't using it anywhere), and you would invoke this function in your constructor, to set up the interval. Whatever you do, you only want to call this method once. You could just put the contents of the function in your constructor.
Finally, since coffeescript returns the value of the last statement from all functions, I throw a true in there, but that might no be necessary.
This is handy in node as well. It's a varient of Tass's answer.
class Widget
constructor: (#options = {}) ->
#options.interval ?= 1000
#setInterval()
timer: ->
console.log 'do something'
setInterval: ->
cb = #timer.bind #
setInterval cb, #options.interval
w = new Widget()