Skip to content

Conversation

pascalbaljet
Copy link
Member

@pascalbaljet pascalbaljet commented Sep 2, 2025

This PR provides a new middle ground between Inertia::merge() and Inertia::deepMerge() so you can have fine-grained control over what should be merged.

In this example, the front-end will replace the entire object, except the data array. The new items will be appended to the existing items.

Inertia::merge(User::paginate())->append('data');

There's also prepend(), and you can also combine multiple calls.

Inertia::merge($complexObject)
    ->append('users', matchOn: 'username')
    ->prepend('messages.data');

You can pass arrays.

Inertia::merge($complexObject)->append(['users', 'messages']);

And even pass a key-value array where the key is the path, and the value the matchOn.

Inertia::merge($complexObject)->append([
    'users.data' => 'id',
    'messages' => 'uuid',
]);

Then there's a new Inertia::scroll() function which you can pass paginated resources.

Inertia::scroll(User::paginate());

In addition to automatically calling append('data') or prepend('data') for you, it sends normalized pagination metadata to the front-end, no matter if you use simple/cursor/full pagination, even wrapped within an Eloquent API resource.

If you don't use Laravel's Paginator, or use a different kind of transformation layer, you may use the two additional arguments that scroll() accepts.

Inertia::scroll($data, wrapper: 'items'); // defaults to 'data'
Inertia::scroll($data, metadata: $instanceOrCallback);

The metadata argument accepts an instance of ProvidesScrollMetadata, or a callback that returns a ProvidesScrollMetadata instance. The callback will receive the $data. For example, if you use Fractal, you could build your own metadata resolver.

use League\Fractal\Resource\Collection;

class FractalScrollMetadata implements ProvidesScrollMetadata
{
    public function __construct(protected Collection $resource) {}

    public function getPageName(): string {}

    public function getPreviousPage(): int|string|null {}

    public function getNextPage(): int|string|null {}

    public function getCurrentPage(): int|string|null {}
}

And use this in the callback:

Inertia::scroll($data, metadata: new FractalScrollMetadata($data));
Inertia::scroll(fn () => $data, metadata: fn ($data) => new FractalScrollMetadata($data));

If you want to be really fancy, you could use a macro to create a shortcut for this.

Inertia::macro('fractalScroll', function (Collection $data) {
    return Inertia::scroll(
        $data,
        metadata: fn (Collection $data) => new FractalScrollMetadata($data)
    );
});

Draft because the tests and front-end PR are not ready yet.

Fixes #762.
See also: inertiajs/inertia#2561 and inertiajs/inertia#2580

@pascalbaljet pascalbaljet changed the title More fine-grained control for Inertia::merge() and a new Inertia::paginate() More fine-grained control for Inertia::merge() and a new Inertia::scroll() Sep 3, 2025
@pascalbaljet pascalbaljet marked this pull request as ready for review September 3, 2025 22:38
@pascalbaljet pascalbaljet merged commit e2ab960 into 2.x Sep 26, 2025
38 checks passed
@pascalbaljet pascalbaljet deleted the merge-improvements branch September 26, 2025 15:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

deepMerge() still replaces the data instead of merging it

1 participant