Eloquent collection returned json - json

How is that possible ? Le's say that in a controller we have something like :
$something = Something:all();
If I just return $something, an json object is returned with content of table {id:1, title :'etc'}
However if I die dump dd($something), I can see $something is an entire collection.
So the return is not returning the collection, is returning json object...?

This is the magic of Laravel, when you return the collection it convert it to jsonautomatically, this is an advantage for building an api.
Note that when a model or collection is cast to a string, it will be
converted to JSON, meaning you can return Eloquent objects directly
from your application's routes!
Check Laravel Documentation (Converting A Model To JSON).

Well, in addition to #Sheikh Heera answer, such conversion happens in the Illuminate\Http\Resonse class here, by checking if the response content is "JSONable", which is true for Illuminate\Support\Collection which Illuminate\Database\Eloquent\Collection inherits from.

Related

return a json encoded attribute as json decoded in laravel

I have a copy of product in order details table saved as json encoded. Now what I want is that when I retrieve it returns a string but I want it to json decoded. I don't want to decode it explicitly I want it implicitly decoded. Some thing in Model like $casts etc.
Any help would be appreciated thanks in advance.
Let's assume your column is named order_details.
You can add this accessor (full doc here: https://laravel.com/docs/8.x/eloquent-mutators#defining-an-accessor) in your Order model.
public function getOrderDetailsAttribute($value)
{
return json_decode($value ?: [], true); //"$value ?: []" ensure a null value will be coverted into an empty array
}
Every time you'll call $order->order_details, it'll decode the json and return it as an array.

Nested object JSON serialization in WebAPI

I am using .NET 4.0, MVC 4, Web API. I have following data structure:
Dictionary<Actor, Int32> TopActorToMovieCount = new Dictionary<Actor, Int32>(10);
And following entry in WebApiConfig:
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
In my Controller, I am returning TopActorToMovieCount this way:
[HttpGet]
public HttpResponseMessage HighestMovies()
{
return Request.CreateResponse(HttpStatusCode.OK, MvcApplication.TopActorToMovieCount);
}
But the JSON output it is giving is:
{"api.Models.Actor":137,"api.Models.Actor":125,"api.Models.Actor":99,"api.Models.Actor":96,"api.Models.Actor":83,"api.Models.Actor":82,"api.Models.Actor":81,"api.Models.Actor":79,"....
Why it is not giving JSON structure for object of Actor?
I am sure that I am missing something, bout couldn't figure out. I tried adding following, but it didn't work:
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
PS: When I switch to XML output, it works fine.
See similar question here: Not ableTo Serialize Dictionary with Complex key using Json.net
In this case, you are using "Actor" as the Key of your dictionary. Dictionary stores key/value pairs. So when creating the JSON response, it interprets the "Actor" as a key which is converted to a string, and the "Int32" as the value thus giving you
{"api.Models.Actor":137} or {key:value}
because
Actor.ToString() would result in "api.Models.Actor"
Here's a link to the definition of Dictionary: https://msdn.microsoft.com/en-us/library/xfhwa508(v=vs.110).aspx

I can't read the _id property of a JSON object stored in MongoDB (MongoLab service)

I have a document on a mongodb on Heroku. Each object in the document has a system generated object id in the form of
"_id": {
"$oid": "xxxxxxxxxxxxxxxxxxxxxxxx"
}
When I make a query and get the response from the server, I stringify the response using JSON.stringify and I log the object on the server console. When I do this the following gets logged:
this is the response: [{"creator":"al","what[place]":"home","what[time [start]":"22:00","what[time][end]":"","what[details]":"","who[]":["joe","kay","mau"],"_id":"xxxxxxxxxxxxxxxxxxxxxxxx"}]
Right after the full object gets logged, I try to log the id to make sure I can access it... I want to then pass the id to a different object so that I can have a reference to the logged object.
I have this right now:
var stringyfied = JSON.stringify(res);
console.log("this is the response: " + stringyfied);
console.log("id: " + stringyfied._id);
but when the item is logged I get
id: undefined
instead of
id: "xxxxxxxxxxxxxxxxxxxxxxxx"
No matter how I try to access the _id property, I keep getting undefined even though it get printed with the console.log for the full object
I've tried:
stringyfied.id
stringyfied["_id"]
stringyfied["id"]
stringyfied._id.$oid
stringyfied.$oid
you need to use JSON.parse(), cause JSON.stringify() is to convert to string, parse is to get the object. stringifiedid is a string
What is being returned is an array with one object in it.
The way to access the _id is with stringyfied[0]._id. However, it would be cleaner to pull the object out of the array instead.
There are a few ways you can do that. If this query will only ever return one result and that's all you'll want, you can use the findOne method instead. If the query may return more than a single document, then you will want to loop through the returned results.
I also agree with #dariogriffo that you'll need to use JSON.parse() on the stringified JSON variable.

Grails JSON Converter

I have a method in my main controller that return a string that I want to render as JSON.
So I am importing "import grails.converters.JSON" and calling
myMethod() as JSON
, and it works fine. But when I need to get some details of the json response in my integration test.
So in my integration test I have:
void testfoo() {
def bar = controller.myMethod();
def bar.name; //fails
JSON.parse(bar.toString()).name; // doesn't fail
....
..
}
any idea why I need to convert it to a string and then again to a JSON, since it already a JSON?
The value you get back from your method is a grails.converters.JSON, which is not a directly accessible JSON tree as such, but simply an object that knows how to serialize itself as JSON when required. If you want direct access to the JSON tree structure then you need to tell the grails.converters.JSON object to serialize itself and then pass that JSON to JSON.parse to turn it into a JSONElement (or one of its subclasses, in this case presumably a JSONObject).

Standardized way to serialize JSON to query string?

I'm trying to build a restful API and I'm struggling on how to serialize JSON data to a HTTP query string.
There are a number of mandatory and optional arguments that need to be passed in the request, e.g (represented as a JSON object below):
{
"-columns" : [
"name",
"column"
],
"-where" : {
"-or" : {
"customer_id" : 1,
"services" : "schedule"
}
},
"-limit" : 5,
"return" : "table"
}
I need to support a various number of different clients so I'm looking for a standardized way to convert this json object to a query string. Is there one, and how does it look?
Another alternative is to allow users to just pass along the json object in a message body, but I read that I should avoid it (HTTP GET with request body).
Any thoughts?
Edit for clarification:
Listing how some different languages encodes the given json object above:
jQuery using $.param: -columns[]=name&-columns[]=column&-where[-or][customer_id]=1&-where[-or][services]=schedule&-limit=5&return=column
PHP using http_build_query: -columns[0]=name&-columns[1]=column&-where[-or][customer_id]=1&-where[-or][services]=schedule&-limit=5&return=column
Perl using URI::query_form: -columns=name&-columns=column&-where=HASH(0x59d6eb8)&-limit=5&return=column
Perl using complex_to_query: -columns:0=name&-columns:1=column&-limit=5&-where.-or.customer_id=1&-where.-or.services=schedule&return=column
jQuery and PHP is very similar. Perl using complex_to_query is also pretty similar to them. But none look exactly the same.
URL-encode (https://en.wikipedia.org/wiki/Percent-encoding) your JSON text and put it into a single query string parameter. for example, if you want to pass {"val": 1}:
mysite.com/path?json=%7B%22val%22%3A%201%7D
Note that if your JSON gets too long then you will run into a URL length limitation problem. In which case I would use POST with a body (yes, I know, sending a POST when you want to fetch something is not "pure" and does not fit well into the REST paradigm, but neither is your domain specific JSON-based query language).
There is no single standard for JSON to query string serialization, so I made a comparison of some JSON serializers and the results are as follows:
JSON: {"_id":"5973782bdb9a930533b05cb2","isActive":true,"balance":"$1,446.35","age":32,"name":"Logan Keller","email":"logankeller#artiq.com","phone":"+1 (952) 533-2258","friends":[{"id":0,"name":"Colon Salazar"},{"id":1,"name":"French Mcneil"},{"id":2,"name":"Carol Martin"}],"favoriteFruit":"banana"}
Rison: (_id:'5973782bdb9a930533b05cb2',age:32,balance:'$1,446.35',email:'logankeller#artiq.com',favoriteFruit:banana,friends:!((id:0,name:'Colon Salazar'),(id:1,name:'French Mcneil'),(id:2,name:'Carol Martin')),isActive:!t,name:'Logan Keller',phone:'+1 (952) 533-2258')
O-Rison: _id:'5973782bdb9a930533b05cb2',age:32,balance:'$1,446.35',email:'logankeller#artiq.com',favoriteFruit:banana,friends:!((id:0,name:'Colon Salazar'),(id:1,name:'French Mcneil'),(id:2,name:'Carol Martin')),isActive:!t,name:'Logan Keller',phone:'+1 (952) 533-2258'
JSURL: ~(_id~'5973782bdb9a930533b05cb2~isActive~true~balance~'!1*2c446.35~age~32~name~'Logan*20Keller~email~'logankeller*40artiq.com~phone~'*2b1*20*28952*29*20533-2258~friends~(~(id~0~name~'Colon*20Salazar)~(id~1~name~'French*20Mcneil)~(id~2~name~'Carol*20Martin))~favoriteFruit~'banana)
QS: _id=5973782bdb9a930533b05cb2&isActive=true&balance=$1,446.35&age=32&name=Logan Keller&email=logankeller#artiq.com&phone=+1 (952) 533-2258&friends[0][id]=0&friends[0][name]=Colon Salazar&friends[1][id]=1&friends[1][name]=French Mcneil&friends[2][id]=2&friends[2][name]=Carol Martin&favoriteFruit=banana
URLON: $_id=5973782bdb9a930533b05cb2&isActive:true&balance=$1,446.35&age:32&name=Logan%20Keller&email=logankeller#artiq.com&phone=+1%20(952)%20533-2258&friends#$id:0&name=Colon%20Salazar;&$id:1&name=French%20Mcneil;&$id:2&name=Carol%20Martin;;&favoriteFruit=banana
QS-JSON: isActive=true&balance=%241%2C446.35&age=32&name=Logan+Keller&email=logankeller%40artiq.com&phone=%2B1+(952)+533-2258&friends(0).id=0&friends(0).name=Colon+Salazar&friends(1).id=1&friends(1).name=French+Mcneil&friends(2).id=2&friends(2).name=Carol+Martin&favoriteFruit=banana
The shortest among them is URL Object Notation.
How about you try this sending them as follows:
http://example.com/api/wtf?
[-columns][]=name&
[-columns][]=column&
[-where][-or][customer_id]=1&
[-where][-or][services]=schedule&
[-limit]=5&
[return]=table&
I tried with a REST Client
And on the server side (Ruby with Sinatra) I checked the params, it gives me exactly what you want. :-)
Another option might be node-querystring. It also uses a similar scheme to the ones you've so far listed.
It's available in both npm and bower, which is why I have been using it.
Works well for nested objects.
Passing complex objects as query parameters of a url.
In the example below, obj is the JSON object to pass into query parameters.
Injecting JSON object as query parameters:
value = JSON.stringify(obj);
URLSearchParams to convert a string to an object representing search params. toString to retain string type for appending to url:
queryParams = new URLSearchParams(value).toString();
Pass the query parameters using template literals:
url = `https://some-url.com?key=${queryParams}`;
Now url will contain the JSON object as query parameters under key (user-defined name)
Extracing JSON from url:
This is assuming you have access to the url (either as string or URL object)
url_obj = new URL(url); (only if url is NOT a URL object, otherwise ignore this step)
Extract all query parameters in the url:
queryParams = new URLSearchParams(url_obj.search);
Use the key to extract the specific value:
obj = JSON.parse(queryParams.get('key').slice(0, -1));
slice() is used to extract a tailing = in the query params which is not required.
Here obj will be the same object passed in the query params.
I recommend to try these steps in the web console to understand better.
You can test with JSON examples here: https://json.org/example.html