Разбор данных JSON из переменной Ruby

Я использую внешний API для получения информации с другого сайта. У меня есть действительный JSON, хранящийся в переменной экземпляра с именем @result. Однако, передавая его в представление, JavaScript не распознает, что это JSON.

Я пробовал следующее:

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

Где структура @result такова:

[{"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"}]

Если я попытаюсь получить доступ к атрибуту «имя» через:

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

Это дает мне

undefined

Еще одна попытка:

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

Это дает мне:

Uncaught SyntaxError: missing ) after argument list

Я также пытался экранировать "", но не понял синтаксиса правильно.
Я знаю, что JSON действителен, потому что я прекрасно использую его с остальной частью моего приложения. Проблема заключается в передаче JavaScript. Он рассматривает его как строку и не будет правильно анализировать ее.

Изменить

Я должен добавить, что в моем контроллере я уже анализирую api_result в JSON через Ruby.

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

Решение

Я заставил его работать со следующим. Контроллер:

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

Вид:

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

Спасибо всем за помощь.


person user3162553    schedule 06.06.2015    source источник
comment
Я считаю, что вам просто нужно сделать var apiData = <%= @result %>;. Первая попытка не сработает, так как вы конвертируете строку в JSON, а не массив или объект. Анализ этой закодированной строки снова вернет строку, т. е. apiData — это строка. apiData[0]["name"] затем получить доступ к свойству name первого символа строки, конечно, не существует. Второй не работает, потому что вы генерируете недопустимый JavaScript. Вероятно, это сработало бы, если бы вы использовали одинарные кавычки. Но опять же, вы можете просто вводить данные непосредственно в JS.   -  person Felix Kling    schedule 06.06.2015
comment
Немного ниже Где структура @result: точно что выводится в HTML?   -  person Cerbrus    schedule 06.06.2015
comment
Да, хотя я включил только один объект из вызова. API от Sunlight Foundation, если это поможет   -  person user3162553    schedule 06.06.2015


Ответы (2)


Вы не можете передать данные @result напрямую в JS, потому что, как вы думаете, это недействительный JSON (заметили хеш-ракеты «=>»?)

Решение состоит в том, чтобы правильно отформатировать данные @result как JSON, используя ruby, а затем передать полученные данные в JS. Для этого вы можете просто сделать:

require 'json'
@result.to_json

И затем, на стороне JS:

var apiData = JSON.parse('<%= @result %>');
person Rodrigo Brancher    schedule 06.06.2015
comment
Вау, ты прав. Не могу поверить, что я не видел гашишную ракету. - person user3162553; 06.06.2015
comment
Подождите, так что я должен разобрать его дважды? Разве вызов @result.to_json уже не анализирует данные в JSON? - person user3162553; 06.06.2015
comment
Разбор в javascript предназначен для преобразования строки JSON в объект. В ruby #to_json преобразует хэш в строку в правильном формате JSON. Когда вы перемещаете эти данные («в виде строки») в javascript, вам нужно проанализировать их обратно в объект, и поэтому вы используете JSON.parse. Другими словами: вы на самом деле «строите», когда используете #to_json в ruby. - person Rodrigo Brancher; 06.06.2015

@result похоже на JSON, преобразованный в структуру Ruby. Хэш JSON:

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

при преобразовании в Ruby и распечатке будет выглядеть так:

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

Поэтому я думаю, что общая идея заключается в том, что в Ruby вам нужно преобразовать @result в строку json. И вы бы сделали это, используя .to_json

Итак, вместо:

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

Я думаю, вы бы использовали:

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

или лучше, чтобы сделать HTML безопасным:

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

Я думаю, что это связано с как преобразовать структуры данных ruby ​​в структуры данных javascript с помощью .js.erb?

person rocky    schedule 06.06.2015
comment
Спасибо за помощь. Я должен был упомянуть раньше, что я использую Sinatra и у меня нет доступного помощника html_safe (по крайней мере, с моим набором драгоценных камней). - person user3162553; 06.06.2015