0

I have following hash in my controller:

@suggested_places = {
      "0": "Barcelona",
      "1": "Madrid",
      "2": "Valencia"
    }

I transform it into a json:

@suggested_places_json = @suggested_places.to_json

Here is the output:

=> "{\"0\":\"Barcelona\",\"1\":\"Madrid\",\"2\":\"Valencia\"}"

In my file.js.erb, I want to play with the information. I want to parse the json into a JavaScript object. I do:

const json = "<%= @suggested_places_json %>";
console.log(json);

With following result:

{&quot;0&quot;:&quot;Barcelona&quot;,&quot;1&quot;:&quot;Madrid&quot;,&quot;2&quot;:&quot;Valencia&quot;}

Why do I have the ugly &quot and not the json that I had in the backend? A json is a string, it should keep its form.

If I try to parse it:

console.log(JSON.parse(json));

I have following result:

Uncaught SyntaxError: Unexpected token & in JSON at position 1
    at JSON.parse (<anonymous>)
    at <anonymous>:6:18
    at processResponse (application-50000f29e1bf2752ae7e56dda39f10dd0f67a47aea5c3f07ed0d933f3e1a256a.js:268)
    at application-50000f29e1bf2752ae7e56dda39f10dd0f67a47aea5c3f07ed0d933f3e1a256a.js:196
    at XMLHttpRequest.xhr.onreadystatechange (application-50000f29e1bf2752ae7e56dda39f10dd0f67a47aea5c3f07ed0d933f3e1a256a.js:251)

Could someone help me find out where I am doing the mistake? What am I missing?

AlbertMunichMar
  • 1,680
  • 5
  • 25
  • 49

3 Answers3

0

first you can't parse a json output since you have already put @suggested_places.to_json so that will be enough to get data,second thing is the &quot is being generated cause of (") put in json, so if you want to remove this &quot you should either decode the output or explode characters like \ " from the output but the best way is the first which is to decode the output

  • If I do a: "Barcelona" I have same problems with the &quot. I don't understand your solution. What are you suggesting? Could you be more precise? – AlbertMunichMar Jan 20 '19 at 19:32
  • you will not need the output result as field but u will need the second thing answer – Lord Legolas Jan 20 '19 at 19:44
0

Two ways to pass data from your controller to the views:

Option 1:

You sent from the view a json request to the controller:

= link_to "load public places", load_public_places_path(format: :json), class: "btn btn-primary", remote: true, id: "loadPublicPlacesBtn"

In your controller, you respond with json format, and the data you want to give back:

def load_public_places
    latitude = params[:lat]
    longitude = params[:lng]
    @suggested_places = NearBySearchApiService.call(latitude, longitude)

    respond_to do |format|
      format.json { render json: @suggested_places.to_json }
      format.js
    end

In the view where you want to display the data, you listen to the ajax request:

:javascript
  document.getElementById('loadPublicPlacesBtn').addEventListener('ajax:success', function(event) {
    console.log(event);
  })

Option 2:

In the view, you send to the controller a JS request:

  = link_to "load public places with js", load_public_places_path, class: "btn btn-primary", remote: true, id: "loadPublicPlacesBtn"

In the controller, you answer for the js request, which is going to be in the load_public_places.js.erb

def load_public_places
    latitude = params[:lat]
    longitude = params[:lng]
    @suggested_places = NearBySearchApiService.call(latitude, longitude)

    respond_to do |format|
      # format.json { render json: @suggested_places.to_json }
      format.js
    end

This time, since you are using erb in the views, you can use the instance variable @suggested_places without calling to_json.

In the view, you select the div that you want, and you append the HTML content (you can store it in a partial)

const divWrapper = document.getElementById("optionCardsWrapper");

divWrapper.innerHTML = "<%= j render "option_cards", suggested_places: @suggested_places %>";

@suggested_places is pure ruby, you don't need to parse it.

The j is a helper method, escape_javascript.

In the partial view you can use the information as a normal ruby object

%h1 option cards

- suggested_places.each do |place|
  = place[:name]
AlbertMunichMar
  • 1,680
  • 5
  • 25
  • 49
0

Searching the internet I found this solution from a few years ago, I tested it in an app with rails 6 and it works quite well.

var contentLibrary = '<%= @content_library.to_json.html_safe %>'

console.log(contentLibrary) // {"id":1,"title":"Welcome","status":"active"

console.log(JSON.parse(contentLibrary)) // { id: 1, title: "Welcome", status: "active" }

Embedding JSON in a Rails 4 JS/ERB template

calrrox
  • 329
  • 4
  • 8