Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ajax:complete fires but ajax:success doesn't in a rails 3 app

I am new to RoR, but have decent success with implementing various features for a small app. Until I hit this issue.. for which haven't found any existing issues/questions. To help narrow down my problem to a generic form, here is what I have:

User Story

User is presented with a form to create topics (name & description), once topic is created user is presented the 'show' page which allows the user to add subtopics. As the user adds subtopics, they are shown to the user on the same page (this is where I am trying to use ajax).

Code Artifacts

model ==> topic_request.rb

class TopicRequest < ActiveRecord::Base
 has_many   :subtopics, :class_name=>"TopicRequest", :foreign_key=>"parent_id"
end

controller ==> topic_requests_controller.rb

class TopicRequestsController < ApplicationController
  expose(:user_topic_requests) {current_user.topic_requests}
  expose(:topic_request)
  expose(:sub_topic_request) {TopicRequest.new}

  def new
  end

  def create
    topic_request.save
    if (topic_request.parent_id != nil)
    parentreq = TopicRequest.find(topic_request.parent_id)
    render :partial => 'subreqs', \
           :locals => {:topic_requests => parentreq.subtopics}, \
           :layout => false
    else
    render :show
    end
  end

  def show
  end

  def index
  end
end

new.html.slim

= simple_form_for topic_request, :html => {:class => 'form-stacked'} do |f|
  = f.error_notification
  fieldset
    = f.input :name, :required => true
    = f.input :description, :required => true
  .actions
    = f.button :submit, "Propose Topic"

show.html.slim

# display the parent topic
= topic_request.name
= topic_request.description

#display the form for accepting subtopic requests
= simple_form_for sub_topic_request, \
                  :url => {:controller => "topic_requests", :action => "create"}, \
                  :remote => true, \
                  :html => {:class => 'form-stacked', \
                            :id => 'new_subtopic_request'} do |f|
  = f.error_notification
  fieldset
    = f.input :name, :required => true
    = f.input :description, :required => true
    = f.input :parent_id, :as => :hidden,\
              :input_html => {:value => topic_request.id}           
  .actions
    = f.button :submit, "Propose Subtopic", \
               :class => "btn", :disable_with => "Please wait..."
#subtopic_requests
  = render :partial => 'topic_requests/subreqs', \
           :locals => {:topic_requests => topic_request.subtopics}

partial ==> _subreqs.html.slim

- topic_requests.each do |onereq|
  = onereq.name
  = onereq.description
  hr

coffeescript ==> topic_requests.js.coffee

jQuery ->
  new_subreq_form = $("#new_subtopic_request")

  if new_subreq_form.length > 0
    new_subreq_form.bind 'ajax:before', (e) ->
      # console.log 'ajax:before'
    new_subreq_form.bind 'ajax:success', (event, data, status, xhr) ->
      $("#subtopic_requests").html(data)
    new_subreq_form.bind 'ajax:failure', (xhr, status, error) ->
      # console.log 'ajax:failure'
    new_subreq_form.bind 'ajax:error', (xhr, status, error) ->
      # console.log 'ajax:error' # parseerror eg
    new_subreq_form.bind 'ajax:complete', ->
      $("#topic_request_name").val("")
      $("#topic_request_description").val("")

Problem

The subtopic creation happens, I see new records in database. The clearing of fields from 'ajax:complete' binding also happens just fine, I see those input fields clearing up. I see topic_requests/_subreqs.html.slim completing with status 200. The 'show' page however is not showing the results of rendering the partial, which is what I am trying to capture in the 'ajax:success'.

Any ideas to help debug or samples that I refer to do this is greatly appreciated.

like image 365
Keen Ed Avatar asked Dec 19 '11 01:12

Keen Ed


3 Answers

Rails 4 solution: add data {type: 'text'}:

= form_for vendor, :remote => true, data: {type: 'text'}

This adds the data-type="text" attribute to the form, which jquery-ujs passes to jQuery's ajax method as parameter dataType.

According to the docs of jQuery's ajax method:

  • if dataType is not specified if is inferred intelligently
  • if json is inferred, the response is parsed into a Js object and returns a parse error on error

This is probably what is happening given the parseerror output you get from 'ajax:error'.


I had the same problem and I did it works writing explicitly the format type of the request

for example

= form_for vendor, :format => :html, :remote => true, :html => {:class => "form form-edit", :'data-widget' => 'edit-vendor-form'} do |f| 

If I don't use :format in that way then I have the same issue that you have.

I hope help. Regards.

like image 28
Franco Brusatti Avatar answered Nov 17 '22 02:11

Franco Brusatti


In my code I have found that any ajax response needs to specifically include :content_type => 'text/json' for ajax:success to ever fire. It's weird but unless your response explicitly includes this it seems the browser doesn't always handle it correctly (esp. firefox).

I don't know if you can apply that to fix your situation exactly, but I hope that information helps.

like image 1
Andrew Avatar answered Nov 17 '22 02:11

Andrew