0

I'm using an external API to pull information from another site. I have the valid JSON stored in an instance variable called @result. However, passing it to the view, JavaScript doesn't recognize that it is JSON.

I have tried the following:

var data = JSON.stringify('<%= @result %>');
var apiData = JSON.parse(data);

Where the structure of @result is this:

[{"name"=>"VONDERSAAR, FRANK J", "fec_id"=>"H4AK00057", "pcc"=>"C00503896", "party"=>"D", "candidate_url"=>"/candidate/2014/vondersaar-frank-j/H4AK00057/", "race_url"=>"/race/2014/H/AK/00/", "ie_url"=>"/outside-spending/#?ordering=-expenditure_date_formatted&candidate_id_checked=H4AK00057", "is_incumbent"=>false, "cycle"=>"2014", "not_seeking_reelection"=>false, "other_office_sought"=>nil, "other_fec_id"=>nil, "election_year"=>2014, "state"=>"AK", "office"=>"H", "office_district"=>"00", "term_class"=>nil, "candidate_status"=>"LP", "total_expenditures"=>"0.00", "expenditures_supporting"=>"0.00", "expenditures_opposing"=>"0.00", "total_receipts"=>"500.00", "total_contributions"=>"0.00", "total_disbursements"=>"400.00", "cash_on_hand"=>"100.00", "cash_on_hand_date"=>"2014-07-31", "district"=>{"race_name"=>"2014 AK-00 (House)", "state"=>"AK", "office"=>"H", "office_district"=>"00", "term_class"=>nil, "id"=>541}, "outstanding_loans"=>"500.00", "cand_is_gen_winner"=>false, "status"=>"Lost in primary"}]

If I attempt to access the "name" attribute via:

console.log(apiData[0]["name"]);

It gives me

undefined

Another attempt:

var apiData = JSON.parse("<%= @result %>");

This gives me:

Uncaught SyntaxError: missing ) after argument list

I have also tried escaping "" but haven't gotten the syntax right.
I know the JSON is valid because I'm using it fine with the rest of my application. It's the handing off to JavaScript that is the problem. It treats it as a string and won't parse it correctly.

Edit

I should add that in my controller I am already parsing the api_result into JSON via Ruby.

api_result = [api call]
base       = JSON.parse(api_result)
@result    = base["results"]

Solution

I got it to work with the following. Controller:

api_result = [raw request]
@result    = api_result.to_json 

View:

var apiData = <%= @result.to_json %>;

Thanks for the help everyone.

3
  • I believe you just have to do var apiData = <%= @result %>;. You first attempt can't work, since you are convert a string to JSON, not an array or object. Parsing that encoded string will return a string again, i.e. apiData is a string. apiData[0]["name"] then access the name property of the first character of string, of course does not exist. The second one doesn't work because you are generating invalid JavaScript. It would probably work if you used single quotes. But again, you could just inject the data directly into JS. Commented Jun 6, 2015 at 16:13
  • Is the bit below "Where the structure of @result is this:" exactly what gets output into the HTML? Commented Jun 6, 2015 at 16:13
  • Yes, although I only included one object from the call. The API is from Sunlight Foundation if that helps Commented Jun 6, 2015 at 17:37

2 Answers 2

0

You can't toss the @result data directly to JS because, although what you think, it is not valid JSON (noted the hash-rockets “=>”?)

The solution is to properly format the @result data as JSON, using ruby, then passing the resulting data to JS. For that you can simply do:

require 'json'
@result.to_json

And then, on JS side:

var apiData = JSON.parse('<%= @result %>');
Sign up to request clarification or add additional context in comments.

3 Comments

Wow, you're right. Can't believe I didn't see the hash rocket.
Wait, so I have to parse it twice? Doesn't calling @result.to_json already parse the data into JSON?
Parsing, in javascript, is ment to transform a JSON String into an Object. In ruby, #to_json transform the Hash into a String in proper JSON format. When you move this data (“as string”) to javascript, you need to parse it back to an Object, and that's why you use JSON.parse. In other words: you are actually “stringifying” when you use #to_json in ruby.
0

@result seems to be JSON that has been converted into a Ruby structure. The JSON hash:

{"name":"VONDERSAAR, FRANK J"}

when converted to Ruby and printed out, will look like:

{"name"=>"VONDERSAAR, FRANK J"}

Therefore, I think the general idea is that in Ruby you need to convert @result to a json string. And you'd do that using .to_json

So instead of:

var apiData = JSON.parse("<%= @result %>");

I guess you'd use:

var apiData = JSON.parse("<%= @result.to_json %>");

or better, to make HTML safe:

var apiData = JSON.parse("<%= @result.to_json.html_safe %>");

I think this is related to how can I convert ruby data structures to javascript data structures with .js.erb?

1 Comment

Thank you for your help. I should have mentioned before that I was using Sinatra and don't have the html_safe helper available (at least with my set of gems).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.