2017-01-11 15 views
1

私は、ユーザーがフィルタや価格を調整し、ajax経由で宿泊施設を更新することができるようにするホテル集約サイトに取り組んでいます。これは、Rails 4とCoffeeScriptとJqueryで構築されています。Rails/Jquery Ajax - SyntaxError:予期せぬ識別子ですが、JSONが有効です

はここでjQueryのコール(CoffeeScriptの)である:時間の

$.ajax '/accommodations/show', 
     type: 'GET' 
     dataType : 'script' 
     data: 
     privates: include_privates 
     shared: include_shared 
     homes: include_homes 
     price_range: price_range 
     start_date: start_date 
     end_date: end_date 
     num_guests: num_guests 
     success: (data) -> 
     #RESPONSE DOES NOT HAPPEN HERE, IS HANDLED IN SHOW.JS.ERB 
     console.log "Success!" 
     console.log data 
     error: (data, status, error) -> 
     console.log 'How embarassing! Something went wrong - please try your search again. ' 
     console.log "Status: #{status}" 
     console.log "Error: #{error}" 

90%、このコードは動作します。時間の他の10%は、サーバーは(大丈夫)200件のステータスを返しますが、jQueryが失敗し、コンソールには次のよう表示されます。

この問題を持つ他のすべてのstackoverflowの質問は、それが無効なJSONが渡されていたように見えます
How embarassing! Something went wrong - please try your search again. 
Status: parsererror 
Error: SyntaxError: Unexpected identifier 

Jqueryに戻る私はshow.js.coffee.erbの問題行を特定しました。ここでは、レールモデルをJSONに変換して、javascriptに渡すことができます。

$('.refresh-loading').hide() 
//Adding the accommodation modules to the left-hand side 
$('#accommodation-modules-wrapper').html("<%= escape_javascript(render partial: 'accommodations/accomm_modules', locals: {properties: @accommodations, slider_min: @price_low, slider_max: @price_high})%>") 
window.init_isotope() 

//Removing the loading icon 
$('.refresh-loading').hide() 

//THIS IS WHERE THE ERROR IS 
//Removing this line fixes the issue 
marker_string = '<script>window.accommodation_markers = <%= raw @accommodations.to_json %>;</script>' 

raw @accommodations.to_jsonの出力は以下の通りです:

[{ 
    "id": 741580, 
    "name": "Gamer's Paradise in Brooklyn!", 
    "google_place_id": "ChIJOwg_06VPwokRYv534QaPC8g", 
    "type_code": "hotel", 
    "external_id": 2243038, 
    "lat": 40.694426, 
    "lng": -73.94636, 
    "location_rating": 9.0, 
    "overall_rating": 9.0, 
    "review_count": 13, 
    "currency_code": "USD", 
    "average_nightly_price": 30.0, 
    "image_url": "https://a2.muscache.com/im/pictures/asdfa-4cf7-4222-9204-619200def457.jpg?aki_policy=small", 
    "url": "https://www.test.com/rooms/13396285", 
    "review_url": "https://www.test.com/rooms/13396285#reviews", 
    "accommodation_cluster_id": null, 
    "created_at": "2016-12-07T11:22:21.319-08:00", 
    "updated_at": "2016-12-14T08:48:51.073-08:00", 
    "usd_average_nightly_price": "30.0", 
    "city_rank": 0, 
    "city_rank_price": 15, 
    "city_rank_reviews": 511, 
    "cluster_rank": 0, 
    "cluster_rank_price": 0, 
    "cluster_rank_reviews": 1, 
    "shared_room": true, 
    "private_room": false, 
    "entire_home": false, 
    "external_uid": null 
}] 

この出力はJSONLintに応じて有効です。この問題をさらにデバッグし解決するにはどうすればよいですか?

+1

@PaulRoubが正しいと思われます。インスタンス変数に代入する前におそらくjsonに変換する必要がありますが、それでも問題がある場合にはそれを検証してください。 – Jeff

+0

@Jeff - コントローラーメソッドで変換(つまり「未処理」)を行うと、同じ問題が残ります。 – CHawk

+1

コントローラアクションでどのように検証しましたか?あなたがコピーしたハッシュは、それがうまくいかないときにインスタンスですか? – Jeff

答えて

1

簡単な例から始めて、どうなるか見てみましょう。あなたはRubyでこのお持ちの場合:

@thing = { :id => 741580, :name => "Gamer's Paradise in Brooklyn!" } 

をし、その後、いくつかのERBにあなたが言う:

thing = '<%=raw @thing.to_json %>' 

を、あなたが出力としてこれを参照してくださいよ:

thing = '{"id":741580,"name":"Gamer's Paradise in Brooklyn!"}' 

とあなたの問題があります:rawでも<%= ... %>でも'を引用/エスケープ/エンコードすることはできません。そのrawコールは、単純にERBエンジンにその引数をHTMLエンコードしないように指示し、HTMLをターゲットにしていないので、あなたはraw機能を使用します。しかし、あなたはより多くを望む、あなたはそれらの引用符をエスケープしたい。

おそらく最も簡単なことは、String#html_safeescape_javascriptを使用することです。しかし、ERBによって生成されたJavaScript文字列の中にJavaScriptがあるので、エスケープ処理を二重にする必要があります。何か嫌なように:

marker_string = '<script>window.accommodation_markers = <%= escape_javascript(escape_javascript(@accommodations.to_json.html_safe)) %>;</script>' 

<script> JavaScriptの文字列内の」牛車が必要ではなかったように、私は強くリファクタリング事の方に傾くと思います。エンコーディング/エスケープの3つのレイヤーは、多少エラーが発生しやすいです。

関連する問題