rails json format - ruby-on-rails

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.

Related

How server respond for html, ajax, xml and json for rails app

In my rails app I send request in html, ajax, xml and json. For xml and json I do it by writing :format => 'json/xml', for ajax we write :remote => true.
But how server know that it has to respond with ajax, xml or json?
One thing I noticed when I send json or xml request it show in the url like below
http://localhost:3000/en/line_items.json
Though Im not sure, this is how server know if he has to give json response. But for html and ajax something like this is don't add in the url. So how server know whether it is ajax or html request?
Request headers are governed by mime-types, which basically determine which type of content / request is being sent
Rails has an in-built handler to manage different responses. As per #hawk's URL on ActionDispatch::Request, you can see this middleware essentially catches the type of request sent from the browser
Respond_To
The real answer to your question is about the respond_to block:
#apps/controller/your_controller.rb
def new
respond_to do |format|
format.html { # do stuff here }
format.js { # do stuff here }
format.json { # do stuff here }
end
end
This will allow you to send various responses depending on the mime-type sent in the request :)

Rails Controller -- just return the processed data (dont load into a view)

I'm new to Ruby and Rails. I just completed a course in Laravel, so I am aware of the MVC system(not a newbie as far as the basic concepts are concerned).
I have a rather simple question,
I am sending a POST request to my RAILS REST API,the body of the post request contains a json encoded string like this--->
Array ( [method] => POST [timeout] => 45 [redirection] => 5 [httpversion] => 1.0 [blocking] => 1 [headers] => Array ( ) [body] => {"post_content":"here is the post","post_title":"here we are ","post_author":"1"} [cookies] => Array ( ) )
As you can see,its coming from my php based blog.
My rails API is supposed to be taking the post content and automatically adding links to certains words, by comparing the words with some stuff that i have in an SQLite database.
Ok, so my problem is this:
I just want the response from the Rails controller, I dont want anything loaded into a view. The Rails Controller - returns the content, with 'a href' tags around words that are found in my database. This is to be sent back as the response to my post request, and i want to access it directly as the body of the response.
As of now I dont know how this is to be done. Laravel has the ability to 'return' whatever you want to , at the end of the Controller Action, but in Rails, everything seems to want to load into a view.
I have researched some questions here and found one which said 'render :nothing => true',but that renders nothing at all.Here is what my code looks like.
def process
content = params['post_content']
##perform db function and get back the content with the links embedded.
##HOW TO RETURN THIS CONTENT.
end
Personally, I think, i have to use the render_to_string method, but I have no idea how to do this.
Any help is appreciated.
Best Regards,
Richard Madson.
Some options to consider:
Render just the raw string as the http response body:
render :text => content
Render a view without the default surrounding layout:
render :layout => false
In that case your view could just be:
<%= #content %>
Or render the content as json:
render :json => { :content => content }
The question is, what do you want returned? Text? XML? JSON?
I'm going to assume you want JSON back based on the JSON going in.
respond_to do |format|
format.json { render json: #someobject }
end
It might be helpful to see the rest of the controller method.
If I understand correctly believe what you are looking for is
render :text => "response"
there is also - JSON, XML, nothing, js, file, etc - more information here http://guides.rubyonrails.org/layouts_and_rendering.html

Not able to fetch json data in RoR

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.

Ajax response from controller

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.

When does "respond_to do |format|" make sense for Javascript?

I saw this code in a Rails controller:
respond_to do |format|
format.js {}
end
I've seen this for XML and HTML formats but not for Javascript.
Is this the way you specify a return format if you use for REST, like if you use replace_html or remote_form_for? I know RJS templates return compiled Javascript so I'm thinking maybe this is where this code might kick in.
If you put code inside the hash symbols(format.js {}), is that what gets send back as javascript to the browser?
It is used when an AJAX request is sent from the browser to a controller. The controller can respond with a script (which is generated by ruby statements in the view) which will be executed on the client.
Rails does a little magic on figuring out what 'template' to send out
in controller:
def foo
end
in view: (app/views/controller/) you can have
foo.html.erb (usual, html template)
foo.rjs (javascript template)
rails will send out the right template back to the browser, HTML for regular requets and RSJ for Ajax requests. You might want to put in javascript code like 'page.replace_html' ..etc in your RJS template. This way, you keep the controller clear of view code.
yuo can always just add the format to the url and see what it responds, /something.js would respond using the format.js code, if you want to use it, you can do the following to avoid rendering your entire layout:
format.js { render :layout => false, :text => #models.to_json }
that would respond with a json string
format.js { render :layout => false }
would require a template called [action].js.erb

Resources