I need to be able to pass data to all views when the user is logged in.
Here is what my AppServiceProvider
currently looks like:
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
if (Auth::check())
{
View::share('key', 'value');
}
}
}
However, the data is never passed to the view because I can't use Auth
(for some reason) in AppServiceProvider
so the if statement condition is never met.
Following a previous solution I found, I tried doing this:
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
View::composer('*', function ($view)
{
if (Auth::check())
{
View::share('key', 'value');
}
}
}
}
This worked, but the problem is that the closure is called whenever a view is rendered.
For example, if my blade template includes 3 other blade templates (which it does), then the closure above will be called 4 times. Explained further here.
So how can I access the user correctly in AppServiceProvider
?
The reason why the Auth
methods do not work in a direct context in the AppSeviceProvider
, is that the Auth system is not loaded yet. In the defined closure, the Auth system will be available, as it always loaded before this closure is executed. Hence, the problem is in the way the view composer is used.
The composer
method only accepts an array (or a string) of view identifiers and an *
. Therefore, the following options are available:
Define multiple views
View::composer(['about', 'contact'], function ($view)
{
if (Auth::check())
{
View::share('key', 'value');
}
}
Define one view, and make this the main parent view for all the relevant pages
You could, for example, define a main.blade.php
and extend this view with all relevant views.
@extends('main')
And just share the main
view:
View::composer('main', function ($view)
{
if (Auth::check())
{
View::share('key', 'value');
}
}
There are other options available, for example filters or a parent controller. Excellent answer here.