Rittersm Rittersm - 1 year ago 204
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 Source

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.
  });
});