My javascript send Ajax request which will invoke a controller function, then the controller function response to the Ajax request. My problem is in the controller response part.
my javascript which send Ajax request to controller:
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState==4 && xmlhttp.status==200){
//RENDER RESPONSE #cars here
}
}
xmlhttp.open("GET","/cars/reserved_cars/"+customer_id,true);
xmlhttp.send();
So, the above ajax request will invoke my CarsController's reserved_cars function with customer_id as parameter.
My CarsController:
class CarsController < BaseController
def reserved_cars
customer_id=params[:customer_id]
#cars = Car.getCars(customer_id)
end
...
end
My controller get all cars by query Car model with customer_id.
Everything works fine, I just don't know how to return the #cars in controller as response of my ajax request to my javascript (the place in my javascript where I commented "//RENDER RESPONSE #cars here")
So, How to get #cars response in my javascript?
Thanks guys, I figured out the solution.
I first convert #cars to string cars_str,
then use render :json => cars_str in my controller,
in my javascript I can get this cars_str string with xmlhttp.responseText
HTTP protocol always transfers the string, if you are trying to return array or other non scalar variable you will fail.
The solution would be to format your variable as a string and then parse it in JavaScript.
You will need to write an ajax response
class CarsController < BaseController
def reserved_cars
customer_id=params[:customer_id]
#cars = Car.getCars(customer_id)
respond_to do |format|
format.js
end
end
end
In your cars view you add reserved_cars.js.rjs that contains the javascript. This file contains your javascript code like:
page.replace_html :cars, :partial => '/cars/car', :collection => #cars
replace_html will replace the inner html of the DOM element with id cars (eg. <div id="cars"></div>) . the partial displays 1 car
I hope this helps
This page
"/cars/reserved_cars/"+customer_id"
Needs to return a page with text on it. This text can then be accessed by accessing the responseText of your xmlhttp object.
if (xmlhttp.readyState==4 && xmlhttp.status==200){
//RENDER RESPONSE #cars here
responseFromCar = xmlhttp.responseText;
}
Where responseFromCar will be the text returned from your request. Then just parse the text as necessary to find the associated info you need.
Note: You could also use responseXML instead of responseText if you are expecting a properly formatted XML page back from your request. This approach would make parsing it a bit easier.
Related
Ok. So I have a small XHR request where json is returned. On success the json is passed like this.
var myArr = JSON.parse(xmlhttp.responseText);
myMainFunction(myArr);
function myMainFunction(arr) {
var vShipTypeID = arr[0].victim.shipTypeID;
}
I need to send vShipTypeID to rails. My goal is to be sending this value back to activerecord and the information returned will go within a js, or json file to the respond_to statement in the controller.
#shipName = InvType.find(vShipTypeID).name
Here's the main idea. The client sends out the ID of the ship to rails, and rails returns the ship's name.
I know how to make the Ajax request.
I don't know how to process the request on the server end. Meaning after rails receives the data, where do I find it, and how to I convert it to be usable so that I can make an activerecord statement out of the value I received from the client?
Anyone?
A simple solution could be defining an action on your ship controller and define a route to it for example define a route in your routes.rb
get "/ship/:id/getname" => "ship#getname"
in your js file
$.get( "/ship/"+vShipID+"/getname")
.done(function(data) {
alert( "Ship name: " + data.name );
})
.fail(function() {
alert( "error" );
});
in you ship_controller.rb
class ship_controller <ApplicationController
....... #other methods
def getname
#shipname = Ship.find(params[:id]).name
if request.xhr
render :json => {name: #shipname} and return
else
redirect_to ship_path(params[:id])
end
end
........ #some other methods
end
You need to handle json requests in your controller check this question for details
for a quick example in your controller create a new action getnamefromid and call that controller from your client.
respond_to do |format|
format.json { render :json => #shipName }
end
I am trying to do everything on a single page. The page is called users/index.html.erb.
On this page I return a simple data base query in json format.
I would like to also return a seperate query in non json format from the same database.
I'm trying to avoid partials for the moment as they make variable handling a bit more complicated that I want for my beginner level.
This is what I have:
class UsersController < ApplicationController
def index
#users = User.including_relationships
#followas= User.find_by name: params[:name]
respond_to do |format|
format.html # index.html.erb
format.json { render json: #users }
end
end
end
but it doesnt work unsurprisingly. How can I get it to work in one action?
Not sure about your purpose of returning two formats of query from a single controller call. It usually happens when you use Javascript heavily (eg. Angular.js). Controller first returns the HTML page including all the HTML template and javascript, then data in JSON is returned in the second round.
So in your users/index.html.erb, you might have something like:
<p ng-repeat='user in users'>{{user.name}}</p>
<script>
// do a AJAX call to retrieve users in JSON format
</script>
Then you will call users/index.json again to retrieve users information in JSON.
In short, your users/index is called twice, once for html, once for JSON.
It might seem unwise to call the same controller method twice just to render different format. In such case, you might consider to embed the JSON data in HTML. In such way, you will only render users/index.html.erb once and parse the data in JSON through Javascript on the client side.
This is my code in my view where I am making an ajax get request to method campaign_creation
$(document).ready(function(){
$("#submit").click(function(){
$.get("/configure_campaign/campaign_creation",{category_name: $("#category_name").val()}, function(data){
$("#category_name").val('');
$("#form_add_category").css("display","none");
alert(data.category_name)
})
})
})
and here is my method code
def campaign_creation
if(params[:page_id] and params[:page_access_token])
abcd=params[:page_id].split("_")
session[:page_id]=abcd[0]
session[:page_access_token] = params[:page_access_token]
else
category=Category.new
category.category_name=params[:category_name]
category.page_id=session[:page_id]
category.save
#category=Category.find(1)
#category.to_json
end
end
I think I should be able to access #category in my variable data. If I simply put data in my alert box I get the complete code of the page and if data.category_name I get the result as undefined.
From the code you've provided for your action alone, you're not going to be rendering a JSON response. Your campaign_creation method is going to try and find a campaign_creation.html.erb file and render a text/html response.
Instead you need to explicitly tell Rails to render JSON data and the end of the action and stop processing.
render json: #category and return
Now you can expect the data variable in your Ajax response to have accesss to the #campaign's :category_name attribute.
i'm trying to render a json string in response to a request like following:
def check_progress
if request.xhr?
render :json=>"{'bytes_expected': #{session[:size]}, 'bytes_recieved': #{session[:size]}, 'last_seq': 0}".to_json
end
end
but in my js code :
$.getScript('contacts/check_progress', function(data){
console.log(data.bytes_recieved)
console.log(data.bytes_expected)
d.renderProgress(data);
});
I get undefined in response to data.bytes_recieved and data.bytes_expected.
what's wrong in my rails code?
I Think your main problem might be that your returning a string which looks like json and is not actually a json hash.
in your render statement you are hand formatting the json as a string... which is fine until you call to_json on it.
to_json is suspose to be passed a hash not a string.
You could try removing the .to_json at the end of your render statement:
render :json=>"{'bytes_expected': #{session[:size]}, 'bytes_recieved': #{session[:size]}, 'last_seq': 0}"
or create a ruby hash then convert it to json:
#ruby_hash = {
:bytes_expected => session[:size],
:bytes_recieved => session[:size],
:last_seq => 0
}
render :json=> #ruby_hash.to_json
The $.getScript method of jQuery inserts a <script> node to the <head> of your HTML document.
With that method your browser won't send the X-Requested-With HTTP header to the server. Because it will be a simple HTTP request not an AJAX one. And your browser is waiting a javascript in the response not a JSON data.
In the jQuery documentation of the $.getScript method is somewhat misleading because it says data in the callback function of the method signature, but it won't give you any data in the callback function, because your browser simply executes the javascript there is no actual payload with this request.
There is to possible solutions:
If you need to load data from cross-domain, then try to remove the request.xhr? condition an use JSONP method and callback
if it's not a cross-domain situation, simply load with a $.getJSON response and don't touch the condition
Update: and I have not seen it but #Barlow pointed it out you need to fix your json generation code in your rails app as he says.
You can simplify your code to:
def check_progress
if request.xhr?
render :json => {'bytes_expected' => session[:size],
'bytes_recieved' => session[:size],
'last_seq' => 0}
end
end
as render :json will do the conversion of hash into JSON object for you. I dont know if this will solve the problem.
On my site I have a simple model called Feed.
I want to make a link/button that will pull the Feed record with id=5 (for example) using AJAX.
The record that has been pulled should be displayed in a partial.
How can I do that ?
Thanks,
Oded
If you use jQuery, you could do sth like this:
In your controller you must respond to ajax request using the respond_to :js. Then you could either render directyl javascript which will be executed on your site, or the way I suggest you, to render json and parse it on the client side.
class YourController < ApplicationController
def index
#model = YourModel.all
respond_to do |format|
format.html
format.json {
render :json => #model.to_json
}
end
end
On the client side, just bind a click handler and then fetch the data using the path to your controller:
$("#your_link_id").click(function() {
$.getJSON('/path_to_your_controller', function(data) {
console.log(data);
});
}
The code is not tested, but it should work in that way.
Note: the console.log works with firefox but not with safari, try using firebug for console output.
Kind of long for a SO answer, but this should get you going:
http://www.tutorialspoint.com/ruby-on-rails-2.1/rails-and-ajax.htm
That's where I got started with AJAX on RAILS