Coder Social home page Coder Social logo

Comments (11)

thoresuenert avatar thoresuenert commented on July 19, 2024 4

@reinink the idea is:

replace a Laravel view with a inertia page and use everything from the core the way it is?

 View::composer(
            'Pages/Profile/*', 'App\Http\View\Composers\ProfileComposer'
        );

Applies the Composer to all Inertia Components.

from inertia-laravel.

raftalks avatar raftalks commented on July 19, 2024 2

I did come across the need to reuse the same set of shareable data for different components. I will share the solution that
I am using which is working for me and may find this useful to anyone else finding this issue.

I used the Larave's powerful macroable feature already included with Inertia.

Inertia::macro('composeWith', function(string $component, array $composeables = []) {

            foreach($composeables as $composeClass) {
                if(class_exists($composeClass)) {
                    $class = new ReflectionClass($composeClass);
                    if($class->implementsInterface(Shareable::class)) {
                        // the Shareable interface ensures that the method share is available
                        (new $composeClass)->share();
                    }
                }
            }

            return Inertia::render($component);
});

and here is how I have used it in the controller

return Inertia::composeWith('Auth/Login', [
      LoginView::class,
     // add more shareable classes
]);

This way it is more controllable on to which commonly shareable set of classes to use and this also gives flexibility to use the same set of shareable classes with different set of components.

Also note that inside the share method of the shareable class, it just uses the share method provided in Inertia to share the data you need as normally you would do elsewhere.

from inertia-laravel.

reinink avatar reinink commented on July 19, 2024 1

One option is to use the existing Inertia::share() functionality, and pass the current Inertia\Response as an argument.

Inertia::share('mydata', function (Inertia\Response $response) {
    if ($response->component === 'Users\*') {
        return [
            // some data
        ];
    }
});

Only issue there is this will always return the mydata key, even if it's null.

from inertia-laravel.

rojtjo avatar rojtjo commented on July 19, 2024 1

I've created a small demo version of my idea here rojtjo/inertia-laravel. Currently it only works using Closure based composers and without wildcard components.

Usage would be something like this:

Inertia::composer('Foo/Bar', function (Response $response) {
    $response->with('foo', 'bar');
});

// Or bind it to multiple components
Inertia::composer(['Foo/Bar', 'Foo/Baz'], function (Response $response) {
    $response->with('foo', 'bar');
});

from inertia-laravel.

rojtjo avatar rojtjo commented on July 19, 2024 1

I really like how clean it's usage looks! You could even replace (new $composeClass) with app($composeClass) to allow dependency injection.

You might have to watch out when using Laravel Octane though as the ResponseFactory is bound as a singleton. This would mean that all following requests would receive all the previously shared data which could contain sensitive data.

This could be solved by tweaking your macro a bit and pass the created response to the share method. Then you just use the with method on the response to add extra props.

Inertia::macro('composeWith', function (string $component, array $composeables = []) {
    $response = Inertia::render($component);

    foreach ($composeables as $composeClass) {
        if (class_exists($composeClass) && $composeClass instanceof Shareable) {
            app($composeClass)->share($response);
        }
    }

    return $response;
});

from inertia-laravel.

reinink avatar reinink commented on July 19, 2024

What specifically do you mean—preassigning data to specific page components, similar to sharing (global) data?

from inertia-laravel.

rojtjo avatar rojtjo commented on July 19, 2024

Exactly that!

Currently I have a group of pages which require the same dataset. Since it's quite a lot of data I don't want to include this on every response using share() but bind it to a specific set of components.

Ideally I'd even have access to the props originally passed to the render() method.

from inertia-laravel.

tanshiqi avatar tanshiqi commented on July 19, 2024

@reinink , I can not get the correct result:

Inertia::share([
            'something' => function (\Inertia\Response $response) {
                return $response->component;
            },
]);

It returns: 'Unresolvable dependency resolving [Parameter #0 [ $component ]] in class Inertia\Response'

from inertia-laravel.

reinink avatar reinink commented on July 19, 2024

Just adding a discussion I had on Twitter, related to this:

Brad:

Sorry to bug. I can't seem to figure this one out or figure an answer. Inertia - I have a Modal that needs access to a simple Eloquent Model. However, this modal can be clicked from all the views. Like a Global Modal. Should I use AppServiceProvider? I guess its only 1 query, so not a big deal.

In case it helps, I'm pasting a screenshot of the use case. In the Modal, I need access to AccountTypes but this should be available on All views (ie button on left side nav - create a new accout).

image

Me:

Hmm, great question.

I think if it's required on ALL views, I'd simply include this information on every request using the shared data functionality.

However, if it's only going to be shown on some pages, I might be inclined to simply load the required data via a classic xhr request when the modal opens.

It's honestly an interesting problem. It makes me think that it might be worthwhile to have some type of "view composer", that would allow you to only share data based on the component name.

Brad:

Thanks for the reply. Yah, I struggled with it for a bit, and then I opted to go for the AppServiceProvider option.

from inertia-laravel.

rojtjo avatar rojtjo commented on July 19, 2024

That's actually an interesting use case which I ran into myself recently. I opted to just include it everywhere for now even though it's not a clean as I'd hope it would be.

View composers can never really work the same as they do in Laravel though, mainly because Laravel will never know which components your 'page' uses. Which makes my earlier solution not suitable for these kind of issues.

My use case, which gave me this idea in the first place, was that I have a group of 'pages' which all require the same submenu. Normally I would just use Inertia::share() in the constructor of my controller but in this case the 'pages' were spread over multiple controllers.

from inertia-laravel.

emjayess avatar emjayess commented on July 19, 2024

I'm sure more complex use cases can and will arise, but the cases outlined in this thread so far (1. Account types, for a picker, 2. a navigational sub-menu) do not strike as cases that necessitate reaching into the database and sending back the data / models repeatedly... at least in the scope of a given user session; which is really just to corroborate that a "global" (or broad) share mechanism ala Laravel's view composers would be welcome...

And I have more experience with those, than with Inertia sharing patterns. To be able to use familiar laravel constructs and patterns and have it "just work" would be attractive, like this idea of hooking into view composers.

from inertia-laravel.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.