4

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!"}]
asked Feb 10, 2013 at 14:02
9
  • Your php seems fine, \u0022 is a quotation mark. Please debug your javascript, the error should be somewhere in your js code. Commented Feb 10, 2013 at 14:56
  • the js is correct, straight from jquery.com, it works when I make manually inline data in an array and send them as a response so the problem is the json... I shouldn't be having quotation marks as \u0022 chars.. (No js there-that's straight the page out of Symfony) Commented Feb 10, 2013 at 15:01
  • try new Response($message). what do you get? Commented Feb 10, 2013 at 15:11
  • [{"id":1,"iam":1,"youare":2,"lat":50.8275853,"lng":4.3809764,"date":{"lastErrors":{"warning_count":0,"warnings":[],"error_count":0 The quotes are correct but there are some entries that I don't know where they're coming from, "lastErrors,warning_count,warnings, those stuff are not in my database.At all. The getjson call now gives: [object Object] [object Object] etc etc.. Commented Feb 10, 2013 at 15:20
  • Very likley there are comming from the serialization process. The json response is actually a string, so try to parse it into an object before using it stackoverflow.com/questions/45015/… Commented Feb 10, 2013 at 15:31

6 Answers 6

4

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;
 }
answered Feb 11, 2013 at 17:30

Comments

2

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;
}
answered Apr 4, 2014 at 18:28

Comments

1

You can use just normalizer without serializer to solve this:

 $normalizer = new ObjectNormalizer();
 $array = $normalizer->normalize($newEntry);
 $entryJSONFile = json_encode($array, JSON_UNESCAPED_UNICODE);
answered Aug 27, 2018 at 8:40

Comments

1

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)

answered Mar 7, 2020 at 11:43

Comments

0

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();
answered Oct 15, 2019 at 8:39

2 Comments

Code-only answers are considered low quality: make sure to provide an explanation what your code does and how it solves the problem. It will help the asker and future readers both if you can add more information in your post. See also Explaining entirely code-based answers: meta.stackexchange.com/questions/114762/…
Added to my answer info.
-2

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))
...
answered Feb 2, 2014 at 17:27

1 Comment

Shouldn't really be telling them to decode and then re-encode something. That'll slow it down nicely.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.