Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Datatables Fractal Laravel Package

yajra/laravel-datatables-fractal

Fractal transformer plugin for yajra/laravel-datatables. Use League\Fractal to shape server-side DataTables JSON responses. Supports Laravel 12 / PHP 8.2+, with optional service provider and vendor:publish config/assets.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package:
    composer require yajra/laravel-datatables-fractal:^12.0
    
  2. Publish config (optional):
    php artisan vendor:publish --tag=datatables-fractal
    
  3. Register the service provider (Laravel < 5.5):
    // config/app.php
    'providers' => [
        Yajra\DataTables\FractalServiceProvider::class,
    ],
    
    (Auto-discovered in Laravel 5.5+)

First Use Case: Basic DataTable with Fractal

use Yajra\DataTables\Facades\DataTables;
use League\Fractal\Manager;
use League\Fractal\Resource\Collection;

Route::get('/users', function () {
    $manager = app(Manager::class);

    return DataTables::of(User::query())
        ->transform(function ($query) use ($manager) {
            return $manager->createData(new Collection($query->get(), new UserTransformer()))
                ->toArray();
        })
        ->make(true);
});

Key Starting Points

  • Laravel DataTables Fractal Docs
  • Fractal Transformers: Define how your models are serialized (e.g., UserTransformer).
  • DataTables Integration: Use ->transform() to inject Fractal into the response pipeline.

Implementation Patterns

Core Workflow: Transformer + DataTables

  1. Define a Transformer (e.g., app/Transformers/UserTransformer.php):
    namespace App\Transformers;
    
    use App\Models\User;
    use League\Fractal\TransformerAbstract;
    
    class UserTransformer extends TransformerAbstract
    {
        public function transform(User $user)
        {
            return [
                'id' => $user->id,
                'name' => $user->name,
                'email' => $user->email,
                'full_name' => $user->first_name . ' ' . $user->last_name, // Computed field
            ];
        }
    }
    
  2. Integrate with DataTables:
    return DataTables::of(User::query())
        ->transform(function ($query) {
            $manager = app(\League\Fractal\Manager::class);
            return $manager->createData(
                new \League\Fractal\Resource\Collection($query->get(), new UserTransformer())
            )->toArray();
        })
        ->addColumn('full_name', function ($user) {
            return $user->first_name . ' ' . $user->last_name;
        }) // Optional: Add DataTables-specific columns
        ->make(true);
    

Common Patterns

1. Nested Relationships

// UserTransformer.php
public function transform(User $user)
{
    return [
        'id' => $user->id,
        'orders' => $this->collection($user->orders, new OrderTransformer()),
    ];
}

2. Dynamic Includes (Eager Loading)

return DataTables::of(User::with(request('includes', [])))
    ->transform(function ($query) {
        $manager = app(\League\Fractal\Manager::class);
        return $manager->createData(
            new \League\Fractal\Resource\Collection($query->get(), new UserTransformer())
        )->toArray();
    });

3. Custom Fractal Serializers

// app/Providers/AppServiceProvider.php
public function register()
{
    $this->app->bind(\League\Fractal\Serializer\DataArraySerializer::class, function () {
        return new \League\Fractal\Serializer\ArraySerializer();
    });
}

4. Reusing Transformers Across APIs

// API Resource (Laravel 8+)
public function toArray($request)
{
    $manager = app(\League\Fractal\Manager::class);
    return $manager->createData(
        new \League\Fractal\Resource\Item($this->resource, new UserTransformer())
    )->toArray();
}

5. Pagination Handling

return DataTables::of(User::query())
    ->transform(function ($query) {
        $manager = app(\League\Fractal\Manager::class);
        $collection = $manager->createData(
            new \League\Fractal\Resource\Collection($query->get(), new UserTransformer())
        );
        return [
            'data' => $collection->toArray()['data'],
            'recordsTotal' => $query->getQuery()->getCountForPagination(),
            'recordsFiltered' => $query->getQuery()->getCountForPagination(),
        ];
    })
    ->make(true);

Integration Tips

  • Leverage Laravel DataTables’ Built-ins: Use ->addColumn(), ->editColumn(), or ->rawColumns() alongside Fractal for hybrid responses.
  • Cache Transformers: For read-heavy APIs, cache transformer instances:
    $manager = app(\League\Fractal\Manager::class);
    $cachedTransformer = cache()->remember('user.transformer', now()->addHours(1), function () use ($manager) {
        return $manager->createData(new \League\Fractal\Resource\Collection([], new UserTransformer()));
    });
    
  • Frontend Agnostic: Output DataTables-compatible JSON while using Fractal for API consistency:
    // Frontend (DataTables.js)
    $.ajax({
        url: '/users',
        data: table.params(),
        success: function (data) {
            table.clear().rows.add(data.data).draw();
        }
    });
    

Gotchas and Tips

Pitfalls

  1. Double Data Loading

    • Issue: Fractal loads the entire collection into memory before transforming, which can cause performance issues with large datasets.
    • Fix: Use cursor() for pagination:
      $manager->createData(new \League\Fractal\Resource\Collection($query->cursor(), new UserTransformer()))
      
  2. Transformer Not Found

    • Issue: Class 'App\Transformers\UserTransformer' not found due to autoloading.
    • Fix: Ensure the Transformers namespace is registered in composer.json:
      "autoload": {
          "psr-4": {
              "App\\": "app/",
              "Database\\Factories\\": "database/factories/",
              "Database\\Seeders\\": "database/seeders/"
          }
      }
      
      Then run composer dump-autoload.
  3. Includes Parameter Conflict

    • Issue: includes parameter (for eager loading) may conflict with DataTables’ internal parameters.
    • Fix: Use request('includes', []) explicitly (as shown in the docs) or alias it in your routes:
      Route::get('/users', function () {
          return DataTables::of(User::with(request('with', [])))->...
      });
      
  4. Fractal Serializer Mismatch

    • Issue: Responses may not match DataTables’ expected format (e.g., missing recordsTotal).
    • Fix: Manually merge DataTables metadata with Fractal output:
      $fractalData = $manager->createData(...)->toArray();
      return array_merge($fractalData, [
          'recordsTotal' => $query->getQuery()->getCountForPagination(),
          'recordsFiltered' => $query->getQuery()->getCountForPagination(),
      ]);
      
  5. Laravel 12+ Pitfalls

    • Issue: app(Manager::class) may fail if Fractal isn’t bound.
    • Fix: Bind Fractal in AppServiceProvider:
      public function boot()
      {
          $this->app->singleton(\League\Fractal\Manager::class, function () {
              $manager = new \League\Fractal\Manager();
              $manager->setSerializer(new \League\Fractal\Serializer\DataArraySerializer());
              return $manager;
          });
      }
      

Debugging Tips

  • Check Fractal Output: Temporarily return raw Fractal output to debug:
    return $manager->createData(new \League\Fractal\Resource\Collection([$user], new UserTransformer()))->toArray();
    
  • DataTables Parameters: Log incoming parameters to ensure they’re passed correctly:
    \Log::info('DataTables params:', request()->all());
    
  • Transformer Validation: Use php artisan fractal:validate (if available) or manually test transformers:
    $user = User::first();
    $transformer = new UserTransformer();
    $data = $transformer->transform($user);
    

Extension Points

  1. Custom Fractal Manager Override the default manager in AppServiceProvider:
    $this->app->singleton(\League\F
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
codraw/framework-extra-bundle
codraw/messenger
codraw/security
codraw/mailer
codraw/contracts
codraw/profiling
codraw/dependency-injection
codraw/tester
codraw/core
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony