Reputation: 14165
Here's my controller method:
public function sendjsonAction()
{
$message = $this->getDoctrine()
->getRepository('AcmeStoreBundle:Message')
->findAll();
$serializer = new Serializer(array(new GetSetMethodNormalizer()), array('message' => new
JsonEncoder()));
$message = $serializer->serialize($message, 'json');
return new JsonResponse($message);
}
Here's my router:
acme_store_sendjson:
pattern: /sendjson/
defaults: { _controller: AcmeStoreBundle:Default:sendjson}
And here's what I get when I go to /sendjson/ :
"[{\u0022id\u0022:1,\u0022iam\u0022:1,\u0022youare\u0022:2,\u0022lat\u0022:50.8275853,\u0022lng\u0022:4.3809764,\u0022date\u0022:{\u0022lastErrors\u0022:{\u0022warning_count\u0022:0,\u0022warnings\u0022:[],\u0022error_count\u0022:0,\u0022errors\u0022:[]},\u0022timezone\u0022:{\u0022name\u0022:\u0022UTC\u0022,\u0022location\u0022:{\u0022country_code\u0022:\u0022??
(and it goes on similarly)
I attempt to make an ajax call (with jQuery) with the following:
$.getJSON('/app_dev.php/sendjson', function(data) {
var items = [];
$.each(data, function(key, val) {
items.push('<li id="' + key + '">' + val + '</li>');
});
$('<ul/>', {
'class': 'my-new-list',
html: items.join('')
}).appendTo('body');
});
And I get a
Uncaught TypeError: Cannot use 'in' operator to search for '1549' in [{"id":1,...
When I change the Response type of Symfony2, I get a list of
[Object] [Object] [Object] [Object] [Object] [Object] ...
What am I doing wrong? Should I be parsing the answer to convert \u0022 to " or is my response faulty from the beginning?
EDIT
I also tried by changing the controller to:
public function sendjsonAction()
{
$encoders = array(new XmlEncoder(), new JsonEncoder());
$normalizers = array(new GetSetMethodNormalizer());
$serializer = new Serializer($normalizers, $encoders);
$message = $this->getDoctrine()
->getRepository('AcmeStoreBundle:Message')
->findAll();
$serializer = $serializer->serialize($message, 'json');
return new Response($serializer);
}
This time I got VALID JSON, (according to Jsonlint) buuttt the headers are not application/json... (makes sense because I am sending a Response and not a JsonResponse...) (but thats what I m trying to avoid as JsonResponse seems to be changing adding weird characters)
[{"id":1,"iam":1,"youare":2,"lat":50.8275853,"lng":4.3809764,"msgbody":"I saw you over there what's up!"},{"id":2,"iam":1,"youare":2,"lat":50.8275853,"lng":4.3809764,"msgbody":"I saw you over there what's up!"},{"id":3,"iam":1,"youare":2,"lat":50.8275853,"lng":4.3809764,"msgbody":"I saw you over there what's up!"},{"id":4,"iam":1,"youare":2,"lat":50.8275853,"lng":4.3809764,"msgbody":"I saw you over there what's up!"},{"id":5,"iam":1,"youare":2,"lat":50.8275853,"lng":4.3809764,"msgbody":"I saw you over there what's up!"},{"id":6,"iam":1,"youare":2,"lat":50.8275853,"lng":4.3809764,"msgbody":"I saw you over there what's up!"}]
Upvotes: 4
Views: 16240
Reputation: 133
your code is encoding in json twice. Use the Response class when you are doing the json encoding yourself with the serializer.
replace return new JsonResponse($message) with return new Response($message)
Upvotes: 1
Reputation: 11
https://www.php.net/manual/en/json.constants.php
https://www.php.net/manual/en/function.json-encode.php
Object \Symfony\Component\HttpFoundation\JsonResponse
to output JSON string uses function json_encode
, by method of object setEncodingOptions
you can set outputting JSON string options by bitwise constants like JSON_UNESCAPED_UNICODE
:
Encode multibyte Unicode characters literally (default is to escape as \uXXXX). Available as of PHP 5.4.0.
$jsonResponse = new \Symfony\Component\HttpFoundation\JsonResponse($arrayForJSON);
$jsonResponse->setEncodingOptions($this->getEncodingOptions()|JSON_UNESCAPED_UNICODE|JSON_NUMERIC_CHECK|JSON_PRETTY_PRINT);
$jsonResponse->send();
Upvotes: 0
Reputation: 101
You can use just normalizer without serializer to solve this:
$normalizer = new ObjectNormalizer();
$array = $normalizer->normalize($newEntry);
$entryJSONFile = json_encode($array, JSON_UNESCAPED_UNICODE);
Upvotes: 1
Reputation: 325
Serialization is the process of normalizing - making an array that represents the object - and encoding that representation (i.e. to JSON or XML ). JsonResponse takes care of the encoding part for you(look at the name of the class) so you can't pass a 'serialized object' otherwise it will be encoded once more. Hence the solution is only normalizing the object and passing it to JsonResponse:
public function indexAction($id)
{
$repository = $this->getDoctrine()->getRepository('MyBundle:Product');
$product = $repository->find($id);
$normalizer = new GetSetMethodNormalizer();
$jsonResponse = new JsonResponse($normalizer->normalize($product));
return $jsonResponse;
}
Upvotes: 2
Reputation: 11
Issue is you are passing a string to JsonResponse and not an array.
Your Controller code is:
...
return new JsonResponse($message)
...
Your Controller code has to be:
...
return new JsonResponse(json_decode($message, true))
...
Upvotes: -2
Reputation: 14165
I Found the answer.
1) It doesn't "really matter" the content-type is not application/json but text/html, as long as the JSON is Valid. The reason my JS wasn't playing was that I was asking for val and not a property of val such as val.msgbody. :
So my Javascript should be
$.getJSON('/app_dev.php/sendjson', function(data) {
var items = [];
$.each(data, function(key, val) {
items.push('<li id="' + key + '">' + val.msgbody + '</li>');
});
$('<ul/>', {
'class': 'my-new-list',
html: items.join('')
}).appendTo('body');
});
In case the Content-Type is a requirement, then the controller could be like that:
public function sendjsonAction()
{
$encoders = array(new JsonEncoder());
$normalizers = array(new GetSetMethodNormalizer());
$serializer = new Serializer($normalizers, $encoders);
$message = $this->getDoctrine()
->getRepository('AcmeStoreBundle:Message')
->findAll();
$response = new Response($serializer->serialize($message, 'json'));
$response->headers->set('Content-Type', 'application/json');
return $response;
}
Upvotes: 4