How to set javascript function as value of node #258

Closed
garrettlancaster opened this Issue Jun 4, 2012 · 6 comments

Comments

Projects
None yet
2 participants
@garrettlancaster

I'm using Rabl with ICanHaz.js and would like to achieve the following json:

{
  name: 'Joe',
  product: function(){ return 2 * 4 }
}

I feel like there should be an easy solution I am missing, but didn't see anything in the docs about bypassing the renderer.

@databyte

This comment has been minimized.

Show comment Hide comment
@databyte

databyte Jun 4, 2012

Collaborator

You want to return a function as part of the value for product or actually process the results server-side and insert the result (of 8)?

In the former, then you can simply make product a string and spit that out.

What are you using to render out the JSON? Rails with a template? What's your attempt at the template so far?

Collaborator

databyte commented Jun 4, 2012

You want to return a function as part of the value for product or actually process the results server-side and insert the result (of 8)?

In the former, then you can simply make product a string and spit that out.

What are you using to render out the JSON? Rails with a template? What's your attempt at the template so far?

@garrettlancaster

This comment has been minimized.

Show comment Hide comment
@garrettlancaster

garrettlancaster Jun 4, 2012

I want to return the javascript function itself as the value of 'product' (so ICanHaz / Mustache evaluates it client-side when rendering the ICanHaz template); unfortunately that means rendering it as a string won't work.

I am using Rails with the a json.rabl template; here's a concept snippet:

object @job
attributes  :id, :name, :status

node :task_info do
  {
    num_tasks: 20,
    percentage: function () {
      return function( num ) {
        return num / 100;
      }
    }
  }
end

I want to return the javascript function itself as the value of 'product' (so ICanHaz / Mustache evaluates it client-side when rendering the ICanHaz template); unfortunately that means rendering it as a string won't work.

I am using Rails with the a json.rabl template; here's a concept snippet:

object @job
attributes  :id, :name, :status

node :task_info do
  {
    num_tasks: 20,
    percentage: function () {
      return function( num ) {
        return num / 100;
      }
    }
  }
end
@databyte

This comment has been minimized.

Show comment Hide comment
@databyte

databyte Jun 4, 2012

Collaborator

Nodes don't just throw together text like that. You're mixing javascript and ruby together when what you really want to do is just dump text out from ruby so that javascript can interpret it.

object @job
attributes  :id, :name, :status

child :task_info do
  attribute :num_tasks

  node :percentage do
    "function() { return 2+2 }"
  end
end

... or something like that. It all depends on what objects are where in @job.

Another option is to use a layout, see: https://github.com/nesquena/rabl/wiki/Using-Layouts

Collaborator

databyte commented Jun 4, 2012

Nodes don't just throw together text like that. You're mixing javascript and ruby together when what you really want to do is just dump text out from ruby so that javascript can interpret it.

object @job
attributes  :id, :name, :status

child :task_info do
  attribute :num_tasks

  node :percentage do
    "function() { return 2+2 }"
  end
end

... or something like that. It all depends on what objects are where in @job.

Another option is to use a layout, see: https://github.com/nesquena/rabl/wiki/Using-Layouts

@databyte databyte closed this Jun 4, 2012

@garrettlancaster

This comment has been minimized.

Show comment Hide comment
@garrettlancaster

garrettlancaster Jun 4, 2012

Sorry, in my haste I butchered the snippet I put up. If it actually just dumped text into the JSON, that would be perfect. Unfortunately, it turns "function() { return 2+2 }" into a javascript string literal which is then treated as such when ICH renders the template.

In other words, your code gives:

{ percentage: "function() { return 2+2 }" }
and I need
{ percentage: function() { return 2+2 } }

Is that clearer?

Sorry, in my haste I butchered the snippet I put up. If it actually just dumped text into the JSON, that would be perfect. Unfortunately, it turns "function() { return 2+2 }" into a javascript string literal which is then treated as such when ICH renders the template.

In other words, your code gives:

{ percentage: "function() { return 2+2 }" }
and I need
{ percentage: function() { return 2+2 } }

Is that clearer?

@databyte

This comment has been minimized.

Show comment Hide comment
@databyte

databyte Jun 4, 2012

Collaborator

Ahh, you're trying to use RABL to write JavaScript but RABL does not. It writes "data" which can be represented in JSON, XML, YAML, etc.

The following is not valid JSON (which you can test at jsonlint.com):

{ "test": function() { return2+2 } }

Mustache does do a trick with executing functions within the hash (represented as data) that's passed into the call to render but it's not actually JSON. What you could do is merge a true JSON object with a JavaScript hash that contains function calls and pass the results into mustache.js/ICanHaz.

With Handlebars (a superset of Mustache features), I separate out the data and the functions by creating helpers. Then I call those from the template.

Sorry I couldn't be of more help but if you really wanted to dig down into it, you probably could get it to escape the quotes for pseudo-strings but it's really outside of the standard use for RABL which is to return valid JSON.

I don't mind reviewing a pull request if you should add that functionality. Others might find it useful.

Collaborator

databyte commented Jun 4, 2012

Ahh, you're trying to use RABL to write JavaScript but RABL does not. It writes "data" which can be represented in JSON, XML, YAML, etc.

The following is not valid JSON (which you can test at jsonlint.com):

{ "test": function() { return2+2 } }

Mustache does do a trick with executing functions within the hash (represented as data) that's passed into the call to render but it's not actually JSON. What you could do is merge a true JSON object with a JavaScript hash that contains function calls and pass the results into mustache.js/ICanHaz.

With Handlebars (a superset of Mustache features), I separate out the data and the functions by creating helpers. Then I call those from the template.

Sorry I couldn't be of more help but if you really wanted to dig down into it, you probably could get it to escape the quotes for pseudo-strings but it's really outside of the standard use for RABL which is to return valid JSON.

I don't mind reviewing a pull request if you should add that functionality. Others might find it useful.

@garrettlancaster

This comment has been minimized.

Show comment Hide comment
@garrettlancaster

garrettlancaster Jun 11, 2012

Ah, makes sense. Thanks for the insight; merging the JSON with the js hash seems to be the best solution at the moment. If I find myself with some spare time down the road, I'll fork and try my hand at adding the functionality.

Ah, makes sense. Thanks for the insight; merging the JSON with the js hash seems to be the best solution at the moment. If I find myself with some spare time down the road, I'll fork and try my hand at adding the functionality.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment