21

I am trying return a JSON response from a controller in Symfony 2. Form example, in Spring MVC I can get a JSON response with @ResponseBody annotattion. I want get a JSON response, no mtter if it is a JSON Array or a Json Object, then, manipulate it with javascript in the view.

I try the next code:

/**
     * @Route(
     *      "/drop/getCategory/",
     *      name="getCategory"
     * )
     * @Method("GET")
     */
    public function getAllCategoryAction() {
        $categorias = $this->getDoctrine()
                           ->getRepository('AppBundle:Categoria')
                           ->findAll();

        $response = new JsonResponse();
        $response->setData($categorias);

        $response->headers->set('Content-Type', 'application/json');
        return $response;
    }

But I get [{},{}] as Response in the browser. I try with $response = new Response(json_encode($categorias)); too, but I get the same result.

2
  • Did you try 'return new JSONResponse($data);'? Commented Jan 28, 2015 at 11:54
  • $categorias is an object. but setData expects an array. Commented Jan 24, 2023 at 11:58

7 Answers 7

25

I think the @darkangelo answer need explainations.

The findAll() method return a collection of objects.

$categorias = $this->getDoctrine()
                   ->getRepository('AppBundle:Categoria')
                   ->findAll();

To build your response, you have to add all getters of your entities to your response like :

$arrayCollection = array();

foreach($categorias as $item) {
     $arrayCollection[] = array(
         'id' => $item->getId(),
         // ... Same for each property you want
     );
}

return new JsonResponse($arrayCollection);

Use QueryBuilder allows you to return results as arrays containing all properties :

$em = $this->getDoctrine()->getManager();
$query = $em->createQuery(
    'SELECT c
    FROM AppBundle:Categoria c'
);
$categorias = $query->getArrayResult();

return new JsonResponse($categorias);

The getArrayResult() avoids need of getters.

Sign up to request clarification or add additional context in comments.

Comments

20

You need to do this (based on previous answer):

public function getAllCategoryAction() {
    $em = $this->getDoctrine()->getManager();
    $query = $em->createQuery(
        'SELECT c
        FROM AppBundle:Categoria c'
    );
    $categorias = $query->getArrayResult();

    return new JsonResponse($categorias);
}

It works perfect with any Query that Doctrine returns as array.

1 Comment

You can improve your answer by using JsonResponse instead of Response. This will avoid duplicate uses of json_encode and custom headers.
6
/**
 * @Route("/api/list", name="list")
 */
public function getList(SerializerInterface $serializer, SomeRepository $repo): JsonResponse
{
    $models = $repo->findAll();
    $data = $serializer->serialize($models, JsonEncoder::FORMAT);
    return new JsonResponse($data, Response::HTTP_OK, [], true);
}

1 Comment

as explain at symfony.com/doc/current/serializer.html add use Symfony\Component\Serializer\SerializerInterface;, I should add also use Symfony\Component\HttpFoundation\JsonResponse;
2

Following the best practices, I managed to do it the following way:

public function index(CityRepository $cityRepository,
                      SerializerInterface $serializer): Response 

Injecting repository & serializer.

$cities = $cityRepository->findAll();

Retrieving an array of objects.

$data = $serializer->serialize($cities, 'json');

Serializing the data into a JSON string.

return new JsonResponse($data, 200, [], true);

Passing the JSON string to JsonResponse.

2 Comments

I get very ugly object "{\u0022id\u0022:105,\u0022name\u0022:\u00223..." how to fix it ?
@ArturO The serializer in this example returns a JSON string; check that the JsonResponse has the last parameter set to true.
1

You need to change your code this way:

/**
 * @Route(
 *      "/drop/getCategory/",
 *      name="getCategory"
 * )
 * @Method("GET")
 */
public function getAllCategoryAction() {
    $categorias = $this->getDoctrine()
                       ->getRepository('AppBundle:Categoria')
                       ->findAll();

    $categorias = $this->get('serializer')->serialize($categorias, 'json');

    $response = new Response($categorias);

    $response->headers->set('Content-Type', 'application/json');
    return $response;
}

If the serializer service is not enabled, you have to enable it in app/config/config.yml:

    framework:
        # ...
        serializer:
            enabled: true

For more advanced options for serialization, you can install JMSSerializerBundle

4 Comments

I get a 500 error: You have requested a non-existent service "serializer".
You have to enable first the serializer service. In app/config/config.yml add this: framework: # ... serializer: enabled: true
I get the solution: $categorias = $query->getArrayResult(); //$response->headers->set('Content-Type', 'application/json'); //return $response; //return $this->render('AppBundle:Front:test.html.twig', array('otra' => $otra)); return new Response(json_encode($categorias), 200);
That's a good solution too. Didn't work using the serializer service? I find to be a better practice to use a serializer
1

Looks like you are trying to put into response a collection. For that you need to setup serializer (or retrieve data as an array).

Look at this doc pages: http://symfony.com/doc/current/components/http_foundation/introduction.html#creating-a-json-response

and

http://symfony.com/doc/current/cookbook/serializer.html.

Comments

0

I suggest the following solution:

/**
     * @Route(
     *      "/drop/getCategory/",
     *      name="getCategory"
     * )
     * @Method("GET")
     */
    public function getAllCategoryAction() {
        $em = $this->getDoctrine()->getManager();
        $query = $em->createQuery(
            'SELECT c
            FROM AppBundle:Categoria c'
        );
        $categorias = $query->getArrayResult();


        return new Response(json_encode($categorias), 200);
}

1 Comment

You should probably use newJsonResponse like you did in your question.

Your Answer

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.