Neil
Neil

Reputation: 5178

Rails AJAX request not processing as JS but */*

My ajax request works, but I do not understand the server logs. When I look at the server logs it says the following for the ajax request:

Processing by UsersController#change_food as */*

I do not know why it is saying */*. I would expect it to say JS like so:

Processing by UsersController#change_food as JS

Here is the entire flow of things. For this ajax request: I simply binded an event listener for when a select box changes, and then I submit an ajax request when the selection changes. Here is that form field:

# _form.html.erb
<div class="field">
  <%= f.label :food_type_id %>
  <%= f.collection_select :food_type_id, FoodType.all, :id, :name, {}, {data: {action: 'food_sel', food_change_js_url: "#{user_food_change_js_path}"}} %>        
</div>

And here is the actual ajax request:

# application.js
$(document).on('turbolinks:load', function() {

  $('[data-action="food_sel"]').on('change', function(){
    var url = $(this).data('food-change-js-url');

    $.ajax({
      url: url,
      type: "GET",
      datatype: "application/js",
      data: {food_type_id: $(this).val()}
    })

  });

});

Here is the relevant route:

# routes.rb 
get 'user_food_change_js', to: 'users#change_food'

Which routes the ajax request to this controller:

# users_controller.rb
def change_food
  respond_to do |format|
    format.js
  end
end

Which renders this view:

# change_food.js.erb
alert("hello world");

I originally hoped that I could just put remote: true on the select box, and that then whenever the selection changes it would shoot an ajax request up to the server. Unfortunately remote: true only works for a couple things: like for your form_for, your form_tag, your links, and your buttons. I couldn't think of a cleaner why of sending an ajax request (via js) to the server when an event is triggered.

Question: I feel like I am doing something unconventional since the server log does not say it is processing by JS but instead */*. Is there a more conventional way to do this? One that will say it is processing by JS?


Update

Based on accepted answer: all I had to do was camelCase the dataType key and set it properly. Everything else staying the same: it got it working:

# application.js
$(document).on('turbolinks:load', function() {

  $('[data-action="food_sel"]').on('change', function(){
    var url = $(this).data('food-change-js-url');

    $.ajax({
      url: url,
      type: "GET",
      dataType: "script",
      data: {food_type_id: $(this).val()}
    })

  });

});

Upvotes: 3

Views: 2214

Answers (5)

gwcodes
gwcodes

Reputation: 5690

Try appending .js to your user_food_change_js_path.

Also - is change_food_js.erb a typo? I would have expected change_food.js.erb (dot instead of underscore)

Upvotes: 2

Paul A Jungwirth
Paul A Jungwirth

Reputation: 24581

The first problem is that keys in Javascript objects are case-sensitive, so datatype is not the same thing as dataType.

Second, the dataType key is not the same as contentType, although if you leave off contentType jQuery will infer it from dataType. In your case you want script, not application/js (as @Ruslan also pointed out).

Putting those together, you want:

$.ajax({
  url: url,
  type: "GET",
  dataType: "script",
  data: {food_type_id: $(this).val()}
})

If that still doesn't work, I would look for places where you are globally setting contentType, e.g. by calling $.ajaxSetup.

Upvotes: 5

Ruslan
Ruslan

Reputation: 2009

How about adding the headers?

headers: {Accept: '*/*;q=0.5, text/javascript, application/javascript, application/ecmascript, application/x-ecmascript'}

Upvotes: 0

ashvin
ashvin

Reputation: 2040

try

contentType: "text/javascript"

Upvotes: 0

Ruslan
Ruslan

Reputation: 2009

try:

dataType: 'script'

that might work

Upvotes: 3

Related Questions