Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

render :json => 'string here' expected result

I have done this a thousand times but I'm still not comfortable with how the render :json handles strings.

To set a scope let's talk about Rails 3

This is how it behaves right now:

... render :json => 'This is the string' ... 

Will be returning to the browser:

This is the string 

That's actually not a valid JSON response :S

Ideally it should be rendering something like this:

"This is the string" 

Even the rails guides say:

You don’t need to call to_json on the object that you want to render. If you use the :json option, render will automatically call to_json for you.

And calling "This is the string".to_json is actually returning "\"This is the string\"" as expected.

"This is the string".to_json #=> "\"This is the string\"" 

Am I so wrong ?

like image 594
robertodecurnex Avatar asked Jul 29 '11 20:07

robertodecurnex


People also ask

How do I check if a JSON string is valid?

To check if a string is JSON in JavaScript, we can use the JSON. parse method within a try-catch block. to check if jsonStr is a valid JSON string. Since we created the JSON string by calling JSON.

How check string is JSON in PHP?

Simple function to validate JSON. If you have to validate your JSON in multiple places, you can always use the following function. function is_valid_json( $raw_json ){ return ( json_decode( $raw_json , true ) == NULL ) ? false : true ; // Yes!

What is a string in JSON?

A JSON string contains either an array of values, or an object (an associative array of name/value pairs). An array is surrounded by square brackets, [ and ] , and contains a comma-separated list of values. An object is surrounded by curly brackets, { and } , and contains a comma-separated list of name/value pairs.


1 Answers

I agree that this is unexpected behavior at first, but it actually makes some good sense.

Consider, for example, what you would expect this to do:

output = {'foo' => 'bar'}.to_json render :json => output 

Even though the to_json is kinda redundant, you expect the result to be {foo: "bar"}. However, note that the result of {'foo' => 'bar'}.to_json is actually a string. So, the above code block is equivalent to:

render :json => '{foo: "bar"}' 

If render were to JSON-encode strings passed to :json, you would get "{foo: \"bar\"}", which is definitely not expected behavior.

So here's the deal: render checks to see if the :json argument is a string. If so, it assumes that it's a JSON string and you already ran to_json, and passes the string along. If not, it runs to_json on the object.

I think the documentation should probably clarify that, but there you have it. Though it's not exactly intuitive at first glance, I would be surprised if it worked any other way.

like image 185
Matchu Avatar answered Sep 21 '22 00:09

Matchu