Не могу понять, как получить ответ JSON, используя remote: true в Rails - PullRequest
0 голосов
/ 11 апреля 2020

ОБНОВЛЕНИЕ: Я обнаружил, что проблема связана с зависимостью библиотеки. У меня не было установлено jquery-rails gem, поэтому мне не требовалась библиотека jquery-ujs в моем приложении. Короче говоря, я использовал синтаксис jquery-ujs, когда у меня была доступна только встроенная функциональность rails-ujs :( (face-palm). Спасибо всем, кто посмотрел и предоставил ответ.


I Я чувствую, что делаю что-то довольно базовое c, но по какой-то причине я не могу понять, что я делаю неправильно. Я могу успешно создать запись асинхронно с AJAX, используя опцию remote: true помощник form_for. Однако простая структура JSON, которую я пытаюсь вернуть, кажется, недоступна в объекте data ответа AJAX. Когда я запускаю console.log(data), я получаю undefined в браузер js консоль.

вот довольно точное представление моего кода:

Вид формы:

= form_for :thing, remote: true, html: { id: 'thing' } do |f|
      = f.text_field :name
      = f.submit 'submit'

код моего контроллера:

def create
    @thing = Thing.new(thing_params)

    if @thing.save
      render json: { message: 'Thank you' }
    else
      render json: { message: 'oh no' } 
    end
end

мой javascript / jQuery:

$(document).ready(function(){
      $('#thing').on('ajax:success', function(e, data, status, xhr) {
        console.log(data)
      }).on('ajax:error', function(e, xhr, status, error){
        console.log(error)
      });
})

Я погуглил как сумасшедший, и я просто в растерянности. Но, возможно, есть что-то действительно простое, которое я пропускаю. Я ценю любые предложения.

1 Ответ

1 голос
/ 11 апреля 2020

Rails U JS по умолчанию отправляет удаленные запросы с типом контента application/javascript.

Если вы хотите запросить JSON, вы присоединяете атрибут data-type="json" к элементу:

= form_for @thing, remote: true, html: { id: 'thing' }, data: { type: "json" } do |f|
  = f.text_field :name
  = f.submit 'submit'

Существует также проблема Turbolinks. Ваш код присоединяет обработчик событий непосредственно к элементам:

$('#thing').on('ajax:success', function(e, data, status, xhr) {
  console.log(data)
};

Хотя это будет работать при начальной загрузке страницы., Он не будет работать, когда Turbolinks заменяет содержимое страницы на Ajax. Вместо этого вам нужно создать идемпотентный обработчик события :

$(document).on('ajax:success', '#thing', function(e, data, status, xhr) {
  console.log(data);
}).on('ajax:error', '#thing', function(e, xhr, status, error){
  console.log(error);
});

. Он присоединяет обработчик события к самому документу, который будет перехватывать событие, когда оно всплывает в DOM. Таким образом, вам не нужно заключать этот код в $(document).ready(function(){ ... });.

. Вы также должны возвращать значимые коды ответов HTTP - вот что будет определять, будет ли Rails U JS запускать 'ajax:success' или 'ajax:error'. Не JSON сообщения, которые являются анти-паттерном.

def create
  @thing = Thing.new(thing_params)

  if @thing.save
    # Tell the client where the newly created object can be found
    head :created, location: @thing
    # or return a json representation of the object
    render json: @thing, status: :created
  else
    # just return a header 
    head :unprocessable_entity
    # or return a JSON object with the errors
    render json: { errors: @thing.errors }, status: :unprocessable_entity
  end
end
...