KRL: using a defaction parameter in an emit block - krl

I tried using a parameter in an emit block within a user defined action like this:
my_action = defaction(css_class) {
emit <| $K(css_class).append("<span>!!</span>"); |>
}
but when that runs you see a console message "css_class is not defined".
How do I set up the parameter so I can use it within the 'emit' block?

There is an environment issue with defactions that is still being resolved. Right now, simply assign a variable to your paramater and your emit will see it. So, something like this:
my_action = defaction(css_class) {
my_class = css_class;
emit <| $K(my_class).append("<span>!!</span>"); |>
}

Related

Can't Access Destructuring Assignment from Complex Object

Given the input value:
input =
name:'Foo'
id:'d4cbd9ed-fabc-11e6-83e6-307bd8cc75e3'
ref:5
addtData:'d4cbd9ed-fabc-11e6-83e6-307bd8cc75e3'
data:'bar'
When I try to destructure the input via a function like this:
simplify: (input)->
{ name, ref, id } = input
...the return value is still the full input or a copy of the input.
Am I missing something simple here? How can I access the destructured value. If you can't access the value via a return, it seems that destructuring has little value outside of locally scoped values.
While this isn't necessarily an advantage, the only way I was able to transpile and get the correct answer was to assign the destructure values to the local scope using # (aka this).
input =
name:'foo'
data:'bar'
id: 12314
key:'children'
ref:1
f = (input)->
{ #name, #id } = input
r = {}
f.call(r, input)
console.log r # Object {name: "foo", id: 12314}
working example - link
If someone has a better way to approach this, please add an answer so I can select it as this doesn't seem like the best way.

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 translation

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.

How do I use a global variable in the same Mongodb script JS file

I have my JS file.
I have a variable declared at the top called:
var aCollection = db.myCollection;
I use this variable to refer to the collection. It's easy, since I can change the name of the collection to process another collection.
Now I want to use this in a function, like this:
fn1 = function(_id) {
// use _id and aCollection
// i get an error if I use "aCollection"
}
And I call the above function like this:
db.eval(fn1, "245");
db.eval executes fn1 on the server in a separate context so it doesn't have access to the global context of its containing script. You'd have to change fn1 to accept aCollection as a parameter and then pass that parameter into your db.eval call.

Scala: Generate a block that conditionally runs another block

In the Circumflex framework, you can map an URL to a block like this:
get("/foo") = {
"hello, world!"
}
which, when browsing to /foo, will show the given string as expected. Now, to write a complete web application, you almost always need some form of authentication and authorisation. I'm trying to write some kind of wrapper for the above construct, so I can write this:
get("/foo") = requireLogin {
"hello, world!"
}
The requireLogin method would then check if the user is logged in, and if yes, execute the given block. If not, however, it should do a redirect to the login page.
Now I somehow can't get the syntax right (i'm still a Scala newbie). How would you do this in a generic fashion?
Try something like this:
def executeMaybe[A](work: => A): Option[A] =
if (util.Random.nextBoolean)
Some(work)
else
None
This executes the passed code with probability 0.5, returning Some(<result delivered by work>), or returns None is the other cases. You can call it either like this:
val v = executeMaybe(42)
or with block notation:
val v = executeMaybe {
// do some work
// provide return value
}
The trick is to use a by-name parameter, signalled by the => symbol. Read more e.g. here: http://daily-scala.blogspot.com/2009/12/by-name-parameter-to-function.html
The way I asked it, Jean-Philippe's answer is correct.
But here's some information specific to Circumflex:
In the Circumflex RequestRouter, the following can be used to implement the required method:
def requireLogin (f: => RouteResponse ): RouteResponse = {
if(loggedIn) {
return f
}
else {
return sendRedirect("/login")
}
}
The reason behind this was getting clear with the hint from Jean-Philippe's answer, and once I remembered that the following call isn't an assignment of a block to some internal data, but is mapped to another method call instead.
So, the call
get("/") = {...}
is actually mapped to this:
get.update("/", {...})
The block is passed in as a By-Name parameter, so the return value of requireLogin must be the same - which, for Circumflex, is RouteResponse, and not a function.
You also can use j2ee container authentication with <login-config> and <security-constraint> stuff inside web.xml