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!"}]
George Katsanos
  • 13,524
  • 16
  • 62
  • 98
  • Your php seems fine, \u0022 is a quotation mark. Please debug your javascript, the error should be somewhere in your js code. – DarkLeafyGreen Feb 10 '13 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) – George Katsanos Feb 10 '13 at 15:01
  • try new Response($message). what do you get? – DarkLeafyGreen Feb 10 '13 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.. – George Katsanos Feb 10 '13 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 http://stackoverflow.com/questions/45015/safely-turning-a-json-string-into-an-object – DarkLeafyGreen Feb 10 '13 at 15:31
  • I somehow still believe my php is wrong.. Or my database's encoding.. – George Katsanos Feb 10 '13 at 16:24
  • Could you post your template also? – Vitalii Zurian Feb 11 '13 at 16:29
  • What do you mean by Template? I am just checking the json page - there's no view, I am just returning the json data.. – George Katsanos Feb 11 '13 at 16:33
  • (Windows Notepad issue) Please, consult this, I shared the problem too and it fixed it: http://stackoverflow.com/questions/10290849/how-to-remove-multiple-utf-8-bom-sequences-before-doctype – Felix Aballi Sep 19 '14 at 14:50

6 Answers6

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;
  }
George Katsanos
  • 13,524
  • 16
  • 62
  • 98
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;
}
Yuri Borges
  • 315
  • 4
  • 14
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);
f0rt
  • 81
  • 1
  • 8
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)

Sepideh
  • 133
  • 1
  • 1
  • 11
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();
EarthLing
  • 1
  • 3
  • 2
    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: https://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers – borchvm Oct 15 '19 at 13:40
  • Added to my answer info. – EarthLing Oct 17 '19 at 12:56
-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))
...
  • Shouldn't really be telling them to decode and then re-encode something. That'll slow it down nicely. – Seer Sep 10 '14 at 13:49