Ajax call to call POST of a model return 404 error
Not sure why there are 2 post calls made.
Is the route the issue?
show.html.erb:
<script type="text/javascript">
var apiKey = '<%= #api_key %>';
var sessionId = '<%= #room.session_id %>';
var token = '<%= #token %>';
var room = '<%= #room %>';
</script>
<%= debug #room %>
<input type="hidden" name="_method" value="put" />
<script>
var session;
var connection_id;
var connectionCount;
initializeSession();
// Connect to the session
session.connect(token, function(error) {
// If the connection is successful, publish to the session
console.log("session connected")
if (error) {
handleError(error);
} else {
session.publish(publisher, handleError);
}
});
session.on("connectionCreated", function(event) {
console.log("connectionCreated");
console.log(room.id);
connectionCount++;
// jqueryFunction("Call from js to jquery");
$.ajax({
type: "PUT",
data: JSON.stringify({ room: {name: 'New_room'}, _method:'put' }),
url: "/rooms/" + room.id + "/connected",
contentType: 'application/json'
}).done(function( msg )
{
alert( "Data Saved: " + msg );
});
}
</script>
room GET /rooms/:id(.:format) rooms#show
PATCH /rooms/:id(.:format) rooms#update
PUT /rooms/:id(.:format) rooms#update
DELETE /rooms/:id(.:format) rooms#destroy
def update
# #room.update_attributes(params[:name])
end
Error:
POST http://localhost:3000/room/6 404 (Not Found)
POST http://localhost:3000/rooms/room 404 (Not Found)
Rails generate put request by inject the hidden field in the form with name of _method and the value put, like this
<input type="hidden" name="_method" value="put" />
so you need to change to this
$.ajax({
type: "POST",
dataType: "script",
url: '/rooms/5',
contentType: 'application/json',
data: {rooms:{name: "New_room"}, _method: "put"}
}).done(function( msg ) {
alert( "Data Saved: " + msg );
});
});
Related
I want to send some data from view to controller in rails through ajax.
I have the following code in
app/view/static/home.html.erb
<script type="text/javascript">
var dummy = "testtext";
$('#finish').click(function() {
$.ajax( {
url: '/finish',
type: 'POST',
data: dummy,
dataType: 'text'
});
});
</script>
<body>
<%= button_to "Finish", {:action => 'finish', :controller => 'static'}, :method => :post, id => 'finish' %>
</body>
in
app/view/static/finish.html.erb
<p><%= #data %></p>
app/controller/static_controller.rb
def finish
#data = params[:data]
end
in routes.rb
post 'finish' => 'static#finish'
My understanding is that on button click the ajax script will be executed and rails action will store the data passed from view. This doesn't seem to work. I'm not sure if my understanding of the flow is right.
Because you are calling params[:data] in the controller, you need to specify that {data: dummy} in the AJAX data section
<script type="text/javascript">
var dummy = "testtext";
$('#finish').click(function() {
$.ajax( {
url: '/finish',
type: 'POST',
data: {data: dummy},
dataType: 'text'
});
});
</script>
Also you might want to respond to your AJAX call in your controller using the following
def finish
#data = params[:data]
respond_to do |format|
format.json { insert_your_code_here }
end
end
Say I have a button on my form, it doesn't submit the form, but it basically goes off to get some more information:
<%= f.button '', class:'hidden', id: 'do_calculation', remote: true %>
How do I tie this up so that when it is clicked it calls a controller action and returns the data?
Should I have something like this on the same page?
<script>
function calculate_close() {
var id = '<%= #thing.id %>';
$.ajax({
url: "<%= calculate_path %>",
data: {
id: id
},
dataType: "script"
})
}
</script>
Here you can create a html button without using form builder like.
<button id="do_calculation">Button</button>
Then you can bind the click event to that button and call the ajax inside that event, like:
$("#do_calculation").on('click', function(){
var id = '<%= #thing.id %>';
$.ajax({
url: "<%= calculate_path %>",
data: {
id: id
},
dataType: "json"
})
})
and in the controller you can use something like:
respond_to do |format|
format.json { render :json => {:message => "success"} }
end
Hope this will help!
I am trying to submit form in react js with Rails.
I am new to React js and it is my first app
I am getting error No route matches [POST] "/"
Using single component(jsx) to submit the form.I am getting routing error.
Following is my code
EDIT
I changed the route and now I got error "InvalidAuthenticityToken in ItemsController#create"
How can i raise or alert variable in in jsx file ?
I add following route in route.rb
resources :items
root :to => redirect("/items")
ItemsController
def index
#presenter = { :action => items_path,
:csrf_token => request_forgery_protection_token,
:csrf_param => form_authenticity_token
}
end
def create
#item = Item.new(item_params)
#item.save
end
private
def item_params
params.require(:item).permit(:name, :price)
end
Index.html.erb
<%= react_component('Form1', {:presenter => #presenter.to_json}, {:presenter => true})%>
Form1.js.jsx
var Form1 = React.createClass({
handeSubmit: function( e ){
e.preventDefault();
// var form = e.target;
// var name = form.querySelector('[name="item[name]"]').value;
// var price = form.queySelector('[name="item[price]"]').value;
var name = this.refs.name.getDOMNode().value.trim();
var price = this.refs.price.getDOMNode().value.trim();
if(!name || !price)
{
return false;
}
var formData = $( this.refs.form.getDOMNode() ).serialize();
var action = this.props.presenter.action
// alert({formData});
$.ajax({
data: formData,
url: action,
type: "POST",
dataType: "json",
});
},
render: function(){
return (
<form ref="form" className="" action={ this.props.presenter.action } acceptCharset="UTF-8" method="post" onSubmit={this.handleSubmit} >
<input type="hidden" name={ this.props.presenter.csrf_param } value={ this.props.presenter.csrf_token } />
<input ref="name" name="item[name]" /><br/>
<input ref="price" name="item[price]" /><br/>
<button type="submit"> Submit</button>
</form>
)
}
});
It looks like, for AJAX requests, you should send the CSRF token as a header, not as a form field.
(Docs: http://api.rubyonrails.org/classes/ActionView/Helpers/CsrfHelper.html#method-i-csrf_meta_tags)
Here's how you could add that header in your case:
var csrfToken = this.props.presenter.csrf_token;
$.ajax({
data: formData,
url: action,
type: "POST",
dataType: "json",
// Before sending, add the CSRF header:
beforeSend: function(xhr) {
xhr.setRequestHeader('X-CSRF-Token', csrfToken);
},
});
Does that work for you?
By the way, one way I work around this is by using react_component for form fields, but using Rails' form_for to make the actual <form> tag. For example,
<%= form_for #item, remote: true do |f| %>
<!-- Rails will add CSRF token -->
<%= react_component("ItemFormFields", item: #item) %>
<% end %>
In the controller a response to an AJAX Request is following:
#response = {resp: "ack"}
render json: #response
JS which handles AJAX is:
$('#some_btn').click(function() {
var valuesToSubmit = $('#some_form').serialize();
var url = $('#some_form').attr('action');
console.log("VALUE: " + valuesToSubmit);
console.log("URL: " + search_url);
$.ajax({
type: 'POST',
url: url, //sumbits it to the given url of the form
data: valuesToSubmit,
dataType: "JSON",
success: function(data) {
console.log("saved");
console.log(data);
}
});
return false;
});
But the problem is that I don't get console messages, instead the page reloads and I get json as text on a new page. How to prevent this "non-true-AJAX" behaviour?
So, I had almost the same problem. In my case, I was using the folliwing link to send the request:
<td>
<%= link_to add_item_path(item),
class: 'ui icon button',
id: "add-item-#{item.id}",
method: :post do %>
<%= fa_icon 'shopping-cart' %>
<% end %>
</td>
My js to send the ajax was:
$(document).ready(function() {
$("a:regex(id,add-item-[0-9]+)").click(function(event) {
event.preventDefault();
var link = $(this).attr("href");
$.ajax({
url: link,
method: "POST",
dataType: "json",
success: function(data) {
console.log(data);
$('#notice-modal').modal('show');
}
});
})
});
and my rails controller action was:
def add
#item = Item.find(params[:item_id])
current_cart << { item_id: #item.id, quantity: 1 }
render json: {quantity: 1}
end
So the problem was I using only event.preventDefault() but wasn't enought. For working fine, I need to use event.stopPropagation(). Like this:
$("a:regex(id,add-item-[0-9]+)").click(function(event) {
event.preventDefault();
event.stopPropagation();
var link = $(this).attr("href");
$.ajax({
url: link,
method: "GET",
dataType: "json",
success: function(data) {
console.log(data);
$('#notice-modal').modal('show');
}
});
})
The event.stopPropagation() is needed because rails component (rails-ujs I think) sent the request elsewhere. You can also remove the method: :post, and will work fine.
Hope I helped!
Do you need to prevent the default form submit action?
$('#some_btn').click(function(event) {
event.preventDefault();
//...
});
I had this problem myself. Turns out, I'd just forgotten to add "//= require jquery_ujs" to my application.js file. As soon as I added it, everything worked fine.
I am trying to pass some parameters from my view via an AJAX call to a custom method fetch_info in my photos controller. My controller does not seem to be receiving the parameters. When I click on an image to initiate the AJAX call, I see the following in my terminal:
Processing by PhotosController#fetch_info as JSON
Parameters: {"id"=>"", "secret"=>""}
Completed 500 Internal Server Error in 267ms
FlickRaw::FailedResponse ('flickr.photos.getInfo' - Photo not found):
app/controllers/photos_controller.rb:38:in `fetch_info'
It looks like the fetch_info method is being called, but the parameters are empty. How should I be passing in my parameters through AJAX?
Here is my view. I also have my javascript in the view for the purpose of just getting this to work.
index.html.erb
<div class="body_container">
<div id="photos_container">
<% #photos_array.each do |p| %>
<%= link_to '#' do %>
<div class='each_photo_container', id='<%="#{p[:id]}"%>' >
<%= image_tag p[:s_url] %>
</div>
<% end %>
<!-- Load Modal onClick -->
<script type="text/javascript">
jQuery(function() {
$('#<%=p[:id]%>').click(function (e) {
//ajax call to fetch photo info
var fetch_id = '<%=p[:id]%>';
var fetch_secret = '<%=p[:secret]%>';
$.ajax({
type: 'GET',
url: '/photos/fetch_info',
dataType: 'json',
data: { 'id' : fetch_id.val(), 'secret' : fetch_secret.val() }
});
return false;
});
});
</script>
<% end %>
<div class="basic_modal">
</div>
</div>
</div>
Here is my photos_controller.rb:
def fetch_info
puts params[:id]
puts params[:secret]
info = flickr.photos.getInfo(:photo_id => params[:id], :secret=> params[:secret])
end
You can use this code:
$('##{p[:id]}').click(function (e) {
//ajax call to fetch photo info
var fetch_id = '#{p[:id]}';
var fetch_secret = '#{p[:secret]}';
$.ajax({
type: 'GET',
url: '/photos/fetch_info',
dataType: 'json',
data: { 'id' : fetch_id, 'secret' : fetch_secret }
});
return false;
})