B Seven
B Seven

Reputation: 45943

How to convert a Javascript object to JSON in Rails?

I have a Javascript object in a partial that looks like this:

_chart.js.erb

{
    chart: {
        animation: <%= @animation %>
    },
    plotOptions: {
       ...

This partial works as expected as part of a view.

I need to convert it to JSON to be used as a config for a command line utility.

What is a good way to load the partial, interpolate the ERB, convert to JSON and return the JSON?

Something like this might work, but seems like a poor solution:

respond_to do |format|
  format.json { 
    js = File.read('app/views/trades/_chart.js.erb')
    hsh = eval(ERB.new(js).result)
    parsed = JSON.parse(hsh)

    render json: parsed.to_json
  }

Upvotes: 0

Views: 352

Answers (2)

B Seven
B Seven

Reputation: 45943

As max mentioned, converting a partial JS file to JSON is probably not a good idea. Here is another approach (and what I ended up using).

class ChartConfig
  class << self
    def for params
      chart: {
        animation: params[:animation]
      },
      plotOptions: {
        ...

Now the controller looks like this:

respond_to do |format|
  format.json { render json: ChartConfig.for(animation: ... }

Upvotes: 0

max
max

Reputation: 101811

To convert a javascript object defined in a ERB template to JSON you actually have to do something like:

js = render_to_string(partial: 'trades/chart', format: :js)
json_string = %x( node -e "JSON.stringify(#{js})" )
json_string.to_json

While any JSON is valid javascript the inverse is not true. Your partial is not valid JSON since the property names are not quoted. Thus you have to pass it though a javascript runtime to convert it into JSON.

This assumes that the partial renders something which actually can be passed to JSON.stringify and you have to deal with the crazy like escaping characters and it will blow up if the partial contains anything but literals or functions that your JS runtime has.

This is not how you build sane applications. If you need use a peice of data outside the view it should not be defined in a view.

Upvotes: 2

Related Questions