Coffeescript translation - coffeescript

If I have this javascript:
function I_did_something(){
this.test.assertExists('#selector', 'exists');
}
casper.then(I_did_something);
The problem is that casper is using call to call the then method meaning that I cannot do something like this:
#I_did_something = ->
#assertExists('#selector', 'exists')
casper.then #I_did_something
Because this does not refer to the global object.
Can anyone suggest how I would translate this into coffeescript without using the window object preferably?

You can use a fat arrow (=>) to bind the function to the current this:
#I_did_something = =>
#assertExists('#selector', 'exists')
That has a similar effect to:
that = #
#I_did_something = ->
that.assertExists('#selector', 'exists')
and I think that's what you're after.

Related

how to refer the parent object in an event handler using Coffeescript fat arrow

Hi I'm new to Js and Coffeescript, here's a situation I feel difficult to refer the property of parent object which is App in the following example
App =
init: ->
this.foo = 'bar'
this.bindEvent()
bindEvent: ->
$('#test').click(this.show)
show: ->
alert this.foo
App.init()
I think the fat arrow may do the trick but once I've changed to show: =>, this in the context of show method refers to the window object, instead of App object that I want to
. Anybody can tell me how to do it right?
http://jsfiddle.net/kZpHX/
When you define your show function, # (AKA this) actually is window so
show: => console.log(#)
will bind show to window. The problem is that you're simply defining an object so there isn't anything to bind to: you aren't defining a class so this is window. You could refer to App explicitly like this:
App =
#...
show: -> alert(App.foo)
Demo: http://jsfiddle.net/ambiguous/3sRVh/
The this.foo in init will do the right thing because saying App.init() sets up the expected this.
You could also hook up the desired this manually:
bindEvent: ->
$('#test').click => #show()
# or
bindEvent: ->
_this = # # JavaScript style
$('#test').click -> _this.show()
Demos: http://jsfiddle.net/ambiguous/byL45/, http://jsfiddle.net/ambiguous/MT8fG/
Or you could create a class for your App instead:
class App
constructor: ->
#foo = 'bar'
#bindEvent()
bindEvent: ->
$('#test').click(#show)
show: =>
console.log(#foo)
new App
That way your show: => will behave the way you expect it to.
Demo: http://jsfiddle.net/ambiguous/byatH/

Correct way to return function value instead of binding in Coffeescript

I can't seem to find a concise answer to this question. What is the correct coffeescriptic way to return the value from _otherInstanceMethod when calling #_instanceMethod instead of the function binding itself?
x = _instanceMethod: () ->
#_otherInstanceMethod key: 'value'
Edit (thanks commenters)
This returns:
x = function () {
[...] # function body omitted
});
Instead of
x = 'some value returned by _otherInstanceMethod'
I would like the value to be returned instead of the function binding to _otherInstanceMethod
Being totally new to Coffeescript, this was my fault. I was calling the instance method like:
#_instanceMethod
instead of
#_instanceMethod()
Sorry for the trouble, voting to delete
In CoffeeScript #something translated into this.something regardless of the underlying variable type. This means you can use # only in conjuction with properties, with methods you still ought to use good old this.

Variables declared with ":" instead of "="

Can someone explain the difference in Javascript between:
var x = something
and
var x : something
I have no idea on where/how to search about it.
I saw the code above at the bottom of page 4 of this document: http://download.unity3d.com/support/Tutorials/2%20-%20Scripting%20Tutorial.pdf
Thanks in advance!
The first one assigns something to a variable x and the other causes a syntax error.
You're probably mixing up assigning a property in an object literal and normal assignment.
var x = something;//assigning a variable
var y = {
x:something//assigning a object property
};
Edit
var target : Transform;
seems to be UnityScript not JavaScript, it looks like it is not assigning a value but rather setting the variable type. see here
UnityScript is not JavaScript
Unity Script vs Javascript
If you're defining vars in an object, you'd use colons.
var obj = {x:my_var};

Unable to modify Coffeescript's global variables in a JQuery listener

Today I was migrating some of my javascript code into coffeescript and got stuck in something really silly but even though I didn't know how to make it work.
I wanted to update the value of a global variable when a click event was triggered, have a look at the code below to see one of my guesses
Here's the code
#activeObject = null
# Some other code
$ ->
$('#header').click ->
if !headerSelected
showMenu '#header-menu', event
else
#activeObject = "#header"
showMenu '#menu-style-header', event
Unfortunately even though the click event was triggered the variable was not getting updated.
I came up with a work around. I created a function that set the value of the variable and called it instead of the assignment and this time it worked.
I just wanted to know why I wasn't able to do it the other way. For me it was a simple operation and it seemed silly to define a new function just for this.
Your problem is that # (AKA this) inside the click handler isn't the same as it is outside so this:
#activeObject = null
and this:
#activeObject = "#header"
are referring to two different activeObjects. You should be able to bind everything with => to get the right this:
$ =>
$('#header').click =>
#...
or better (IMHO), just refer to window.activeObject directly in both places so that it is obvious to everyone that you're referring to a global variable:
window.activeObject = null
$ ->
$('#header').click ->
if !headerSelected
showMenu '#header-menu', event
else
window.activeObject = "#header"
showMenu '#menu-style-header', event
Alternatively, you could stop using globals altogether in favor of, perhaps, a data attribute:
$ ->
$('#header').data 'activeObject', null
$('#header').click ->
if !headerSelected
showMenu '#header-menu', event
else
$(#).data 'activeObject', '#header'
showMenu '#menu-style-header', event
I think the confusion is about the usage of #, which is basically just a shortcut for this.
If you compile your code and see what CoffeeScript compiler it produces, the confusion becomes clear
this.activeObject = null;
$(function() {
return $('#header').click(function() {
if (!headerSelected) {
return showMenu('#header-menu', event);
} else {
this.activeObject = "#header";
return showMenu('#menu-style-header', event);
}
});
});
if activeObject is global you whould reference to it
window.activeObject = null
and
window.activeObject = "#header";
in both occurences in this code, cause one might be tempted to use it without window in second occurence, but that will cause a new local variable to be implecitly defined.
Generally when starting with CoffeeScript, its usefull to try small snipets like this in
http://coffeescript.org/ on the Try Now Tab

Coffeescript and markup based JS execution

From another thread here I found this great tutorial on markup based JS execution
Garber-Irish solution:
http://www.viget.com/inspire/extending-paul-irishs-comprehensive-dom-ready-execution/.
I'm checking out how I can do parts of this in Coffeescript.
This works OK:
SITENAME.surveys.show = ->
alert "Hello CoffeeScript"
Which renders out:
SITENAME.surveys.show = function() {
return alert("Hello CoffeeScript");
};
This one is not so happy:
SITENAME.surveys.new = ->
alert "Hello CoffeeScript"
SITENAME.surveys["new"] = function() {
return alert("Hello CoffeeScript");
};
I'm new to Coffeescript and doing a codeschool.com course on it now.
I guess the "new" keyword is special for coffeescript.
Is there any workaround for this?
Thanks!
new is special in JavaScript and CoffeeScript is aware of this so it's emitting code that will actually work even though it's bad practice to name methods using reserved keywords.
If you need to use new, you can use [] to define the function:
SITENAME.surveys['new'] = ->
alert "Hello CoffeeScript"
and to call it:
SITENAME.surveys['new']()
Demo: http://jsfiddle.net/ambiguous/Y3qnt/
A quick review of your link suggests that you'll be accessing the function with something like:
controller = 'surveys'
action = 'new'
SITENAME[controller][action]()
So it doesn't matter what the methods are called as you'll always be referring to them by their (string) name anyway.