Comments (11)
@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.
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.
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.
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.
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.
What specifically do you mean—preassigning data to specific page components, similar to sharing (global) data?
from inertia-laravel.
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.
@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.
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).
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.
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.
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)
- Router events runs multiple times. HOT 5
- JSON response error on subdomains - Firefox HOT 1
- Inertia with supervisor SSR error HOT 1
- SSR (react) error ui doesn't match initial ui when including prop having html
- ✨Feature Request: Support `ziggy` 2.0 HOT 4
- fails testing nested pros
- External JS files not working unless you manually reload the page HOT 1
- image upload help HOT 2
- Laravel 11 support HOT 2
- There is no automatic follow protocol, http is used under https, how to solve it HOT 4
- Laravel 11 update and Nova issue HOT 2
- Vue Watch not working upon redirect route HOT 2
- Problem with SSR HOT 1
- Force app.blade.php to reload HOT 2
- Should Inertia middleware call session()->setPreviousUrl? HOT 6
- - HOT 1
- redirection to /dashboard after login does not work HOT 1
- Prevent a webpage from navigating away HOT 1
- Release notes for 1.0 could make it more clear that "Fix URL generation (#592)" is a breaking change HOT 5
- Ziggy2.0 and Laravel11 and Breeze for Inertia + React, TypeScript and SSR starter kit throws error on initial setting HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from inertia-laravel.