Rittersm Rittersm - 3 months ago 34
Ajax Question

Ajax causing error: Started POST "/[object%20Object]" on form submit

I'm using Rails to create a page with the ability to submit contact information and create a contact object. The controller for the Contact creation is:

def create
@contact = Contact.new(contact_params)
if @contact.save
render json: @contact, status: :created
else
render json: @contact.errors.full_messages, status: :unprocessable_entity
end
end


with contact_params of:

def contact_params
params.require(:contact).permit(:name, :email, :phone, :company, :message)
end


The form submits and creates objects fine if I handle everything a redirect but I want to handle the creation with JS. I've used this method before on form submission with no problems but for some reason when I run:

$(document).ready(function(){
$('#new_contact').on('submit', function(ev){
ev.preventDefault()
$.post({
url: $(ev.target).attr('action'),
data: new FormData(ev.target),
processData: false,
contentType: false,
success: function(data){
$('#new_contact').append('<div class="col-xs-12 col-sm-6 col-sm- offset-3"><h3>Thanks for contacting me,' + data.name + '. I will get back to you as soon as I can.</h3></div>')
document.getElementById('new_contact').reset()
$('#new_contact input[type="submit"]').prop('disabled', false)
},
error: function(error){
$('#new_contact').append('<div class="col-xs-12 col-sm-6 col-sm-offset-3"><h3>Sorry, I need at least a name and valid e-mail.</h3></div>')
$('#new_contact input[type="submit"]').prop('disabled', false)
}
})
})
})


It hits the post request and my server returns with the error:

ActionController::RoutingError (No route matches [POST] "/[object%20Object]"):

I've never encountered this error before and I'm not sure how to go about fixing it. Any help is appreciated.

Answer

Try using Rails' remote option for the form, which is a built-in method of handling forms with AJAX.

Your form (in your view) should look like this:

<%= form_for @contact, url: url_for(:controller => :contacts, :action => :create), remote: true, 'data-type': :json do |f| %>
  <!-- insert the rest of your form here -->
<% end %>

Your controller can stay as it is (it just needs to return JSON to the form's AJAX requests, which it's already doing), and your JS should change to this:

$(document).ready(function() {
  $("form#new_contact").on('ajax:success', function(event, data, status, xhr) {
    // The returned JSON structure is available in data.
    $('#new_contact').append('<div class="col-xs-12 col-sm-6 col-sm-  offset-3"><h3>Thanks for contacting me,' + data.name + '. I will get back to you as soon as I can.</h3></div>');
    document.getElementById('new_contact').reset();
    $('#new_contact input[type="submit"]').attr('disabled', false);
  });

  $("form#new_contact").on('ajax:error', function(event, xhr, status, error) {
    console.log("AJAX request failed.");
    // Do something about the failure so the user knows it happened.
  });
});