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

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.

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

Related

Gon variable not passing to js from rails controller during Ajax request

I'm trying to create a jackpot betting site (just as a challenge). I have a method in my controller to update the pot when a user adds money to the pot. I display the pot total on the homepage and would like to update it with Ajax as soon as someone adds money to the pot. I'm using the gon gem to pass variables such as the pot total from my controller to my javascript. It works when the page is reloaded but not when the update method is called with ajax.
Heres my PagesController:
def home
#jackpot = Jackpot.last
gon.pot = #jackpot.pot
end
JackpotsController:
def update
#jackpot = Jackpot.find(params[:id])
if params.has_key?(:amount)
#jackpot.update(pot: #jackpot.pot + params[:amount].to_f)
gon.pot = #jackpot.pot
end
respond_to do |format|
format.js
end
end
Javascript: (In the url the :id is hardcoded for now)
$("#bet-btn").click(function() {
$.ajax({
type: "POST",
url: "/jackpot/update/21",
datatype: "json",
success: function() {
console.log("Pot size: " + gon.pot);
updatePot();
},
error: function() {
console.log("error")
}
});
});
This updates the donut progress bar for the pot
function updatePot() {
updateDonutChart('#jackpot-donut', gon.pot , true);
}
Button to place bet: (amount also hardcoded)
<%= link_to "Place Bet", update_pot_path(#jackpot, :amount =>
0.1), method: :post,:remote => true, id: "bet-btn", class: "btn btn-info btn-lg" %>
I'm pretty new to rails and especially javascript/ajax so any help would be appreciated. Thanks!
In the controller, simply respond to JSON:
respond_to do |format|
format.json { render json: { pot: #jackpot.pot } }
end
Specify the dataType when posting with $.ajax. Notice that the new data is bieng passed to the success function, so it's not gon.pot, but data.pot.
$.ajax({
dataType: "json",
url: url,
data: data,
success: function(data) {
console.log('pot', data.pot);
}
});

Rails 4: Ajax 400 Bad Request

I'm trying to upload a data_uri image from my webcam by ajax with rails uising this gem
For that I have a custom function on my PicturesController.rb:
def upload_image
data_uri = params[:data_uri]
#picture = Picture.new(picture_params)
#picture.user_id = current_user.id
if data_uri
#picture.photo = data_uri
end
#picture.save
end
and the javascript on my page:
function save_photo() {
Webcam.snap( function(data_uri) {
$.ajax({
type: 'POST',
url: '/pictures/upload',
async: true,
data: { data_uri: data_uri }
})
.done(function () {
console.log(data_uri);
});
// shut down camera, stop capturing
Webcam.reset();
} );
}
I'm also use the gem rack-cors to solve cross domain problems.
My route.rb
resources :pictures do
collection do
post 'upload', :action => :upload_image
end
end
But when I call the ajax function I getting the 400 (Bad Request)
The console show the error:
ActionController::ParameterMissing - param is missing or the value is empty: picture:
Has anyone had this problem before?
Thanks!

How to work with rails render with ajax javascript request

I have action in controller
def login
#message = params[:mess]
#user = 1
render :rend_log_form
end
the view - rend_log_form.js.erb
l = $("#log_form");
console.log(<%= #message %>);
l.html("<%= j(render(partial: 'login/log_form', locals: {user: #user})) %>");
and some javascript code
$.ajax({
type: "POST",
url: "/login",
data: {mess:"eee"},
success:function(data) {
console.log("SUCCESS POST");
console.log(data);
},
error:function(data) {
console.log("ERROR POST:");
console.log(data);
}
});
action and controller works ok if use link_to with remote: true, but with my javascript code I have in browser console:
ERROR POST:
Object
the Object.responseText - the code of rend_log_form.js.erb
How to render the form with javascript?
Thanks to Hary Bomrah, adding dataType:"html" to ajax call in js code has helped.

Capybara redirecting to JSON response

I've got a form in my rails application that sends data remotely to a controller action. There is then JavaScript that waits on a successful AJAX response and then updates segments of the page.
When testing with Turnip, Rspec and Capybara, the current_page is redirected to the JSON response instead of staying on the page like I expect.
Here is some of the code:
The controller action being hit
def update
#conversation.update(conversation_params)
#conversation.save
render json: #conversation, serializer: ConversationSerializer
end
The form
= simple_form_for(convo, remote: true, method: :json) do |f|
- f.fields_for :messages, Message.new(conversation: f.object) do |msg|
= msg.input :text, label: 'Message'
= msg.submit 'Post Message', id: 'message-submit'
The Coffeescript listening for success
$(document).on 'ajax:success', 'form[data-remote]', (xhr, data, status) ->
new_message_id = data.conversation.conversation_messages.pop().id
$.get '/conversation_messages/'+new_message_id+'/partial', (data) ->
$('#conversation .message').last().after(data)
$(document).on 'ajax:success', 'a[data-remote]', (xhr, data, status) ->
location.reload()
$(document).on 'ajax:success', 'form[data-remote]', (xhr, data, status) ->
location.reload()
The test that is showing the wrong content
step 'I say :message' do |message|
fill_in 'Message', with: message
click_on 'Post Message'
end
step 'I see the conversation message :message from :username' do |message, username|
expect(page).to have_selector('.conversation-message-sender', text: username)
expect(page).to have_selector('.conversation-message-text', text: message)
end
You need to be using a JavaScript capable driver for ajax submissions to work - see https://github.com/jnicklas/capybara#drivers

What am I doing wrong with this AJAX request using a form_for in Rails 4?

I'm trying to do a form submission through AJAX in Rails and I am not too sure what is wrong here. I got everything to work using "remote: true" but I want to gain a better understanding of how the AJAX works with jQuery. This is my javascript code:
$(document).ready(function(){
$("#new_user_friendship").on("submit", function(event){
event.preventDefault();
var friendId = $("#user_friendship_friend_id").val();
var _this = $(this);
$.ajax({
url: "/user_friendships",
data: _this.serialize(),
method: "POST",
dataType: "json",
success: function(data){
console.log(data);
friendButton.hide();
$(".friend-request-form").html("<p>Friend request sent</p>");
}
});
});
});
I am suspecting this line url: "/user_friendships/new?friend_id="+friendId containing the url is the culprit of my errors. I wrote this because a hidden field is being passed as a person's friend id but it throws a "404 error", I've also tried url: "/user_friendships" which doesn't return any errors but it also doesn't properly execute the Javascript as I expected.
This is the corresponding form_for that the AJAX request is sent to:
<div class="friend-request-form">
<%= form_for current_user.user_friendships.build(friend_id: #user), id: "new_user_friendship", method: :post do |f| %>
<%= f.hidden_field :friend_id, value: #user.id %>
<%= submit_tag "Send friend request", class: "button radius tiny", id: "friend-request-button" %>
<% end %>
</div>
What this form does is it sends a friend request to another user using a hidden field.
And in my user_friendships_controller.rb I have this code:
def create
if params[:user_friendship] && params[:user_friendship].has_key?(:friend_id)
#friend = User.find(params[:user_friendship][:friend_id])
#user_friendship = UserFriendship.request(current_user, #friend)
respond_to do |format|
if #user_friendship.new_record?
format.html do
flash[:error] = "There was a problem creating that friend request."
redirect_to user_path(#friend)
end
format.json {render json: #user_friendship.to_json, status: :precondition_failed}
else
format.html do
flash[:success] = "Friend request sent"
redirect_to user_path(#friend)
end
format.json {render json: #user_friendship.to_json, status: :precondition_failed}
end
end
else
flash[:error] = "Friend required"
redirect_to root_path
end
end
If anyone can provide any suggestions or feedback that'd be great!
UPDATE:
Now that I added in data: _this.serialize() and changed the url to: url: "/user_friendships" I'm now getting a 412 (Precondition Failed) error. Despite this error the data is actually being saved into the database. Does anyone know why I'm getting this 412 (Precondition Failed) error?
There is something I do not understand, with the dataType json, you said that you had a precondition failed status right ?
But you wrote
format.json {render json: #user_friendship.to_json, status: :precondition_failed}
So I don't think there is any problem, indeed, it seems to work fine, as you explicitly passed the status in your render command, try removing it and I think you will have a 200 (success) status instead.
Of course, you can keep the previous post ajax request, or use this short version
$.post(
/user_friendships',
{ user_friendship: { friend_id: friendId } },
function(){
console.log(data);
friendButton.hide();
$(".friend-request-form").html("<p>Friend request sent</p>");
},
'json')
Add a data attribute to the post params instead of passing it in the url:
$.ajax({
url: "/user_friendships",
data: { user_friendship: { friend_id: friendId } }, // <<< Updated
method: "POST",
dataType: "json",
success: function(data){
console.log(data);
friendButton.hide();
$(".friend-request-form").html("<p>Friend request sent</p>");
}
});
Update
The url should be /user_friendships, assuming that you're using RESTful actions. Have a look to this article about REST in Rails.
Also, when you do an AJAX request like this, your are not sending the rails authenticity tokens that are crated by the form helper. This may be the cause of your 412 (Precondition Failed) error.
See: Understanding the Rails Authenticity Token

Categories