Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trying to remove data in Fractal by implementing ArraySerializer in Laravel 5.2

I've got the API working using the standard process, but I want to remove the data namespace from the JSON output. I see I need to implement ArraySerializer, I have been through the Fractal docs, but I can't work out where I need to added it in Laravel 5.2

I found this answer but I'm just getting the same output at the line of code I commented out:

class TrackController extends ApiController
{
    public function index()
    {
        $tracks = Track::all();
        //return $this->respondWithCollection($tracks, new TrackTransformer);
        // Same response as the commented out line above
        $response = new \League\Fractal\Resource\Collection($tracks, new TrackTransformer);
        $manager = new \League\Fractal\Manager();
        $manager->setSerializer(new \League\Fractal\Serializer\ArraySerializer());
        return response()->json($manager->createData($response)->toArray());
    }

    public function show($id)
    {
        $track = Track::find($id);
        return $this->respondWithItem($track, new TrackTransformer);
    }
}

Also, I'm implementing this on a specific controller, even if I got this working, where do I add the code/class so I can get ArraySerializer output for all my controllers?

I've posted this on Github if that helps.

like image 351
Jack Barham Avatar asked Mar 28 '16 13:03

Jack Barham


2 Answers

You need create own MySerializer extends of DataArraySerializer and use it instead of default. Default DataArraySerializer have three methods and in each of them need change return values to this:

use League\Fractal\Serializer\DataArraySerializer;

class MySerializer extends DataArraySerializer
{
    /**
     * Serialize a collection.
     *
     * @param string $resourceKey
     * @param array  $data
     *
     * @return array
     */
    public function collection($resourceKey, array $data)
    {
        return $data;
    }

    /**
     * Serialize an item.
     *
     * @param string $resourceKey
     * @param array  $data
     *
     * @return array
     */
    public function item($resourceKey, array $data)
    {
        return $data;
    }

    /**
     * Serialize null resource.
     *
     * @return array
     */
    public function null()
    {
        return [];
    }

}

So you change the behavior of the serialize mechanism and get result as you wish.

like image 78
Stanislav Avatar answered Nov 03 '22 03:11

Stanislav


If you use spatie/laravel-fractal package or spatie/fractalistic, then you can remove the data key from the results by using the Spatie array serializer Spatie\Fractalistic\ArraySerializer() instead of the Fractal's default serializer.

You can use is like this:

Fractal::create()
   ->collection($books)
   ->transformWith(function($book) { return ['id' => $book['id']];})
   ->serializeWith(new \Spatie\Fractalistic\ArraySerializer())
   ->toArray();

This will return..

[
    ['id' => 1],
    ['id' => 2]
]

Instead of..

[
    'data' => [
        ['id' => 1],
        ['id' => 2]
    ]
]

Or, if you want to use the Spatie serializer globally, add it in the config/fractal.php file like this:

<?php

return [
    /*
     * The default serializer to be used when performing a transformation. It
     * may be left empty to use Fractal's default one. This can either be a
     * string or a League\Fractal\Serializer\SerializerAbstract subclass.
     */
    'default_serializer' => new Spatie\Fractalistic\ArraySerializer(),
    .
    .
    .
];

More info, see: Using a serializer

like image 45
Amr Avatar answered Nov 03 '22 05:11

Amr