1

I'm trying to run a user-related query to fetch data to appear in the top bar of my site on every view.

I've created a new BaseController according to the first answer here:

How to pass data to all views in Laravel 5?

and that's working for a simple test (just sharing a typed-out variable), but when I try and use Auth::user()->id in the __construct method of BaseController (which in my other controllers always returns the ID of the currently logged in user), I get Trying to get property 'id' of non-object.

I've tried adding use App\User at the top of BaseController (even though it isn't usually needed) and also tried adding in the bits for Spatie laravel-permission plugin, but neither has any effect.

I tried dd on Auth::user() and just get 'null'. My feeling is that the user details maybe haven't been loaded at this stage, but BaseController extends Controller same as MyWorkingController extends Controller so I'm not sure why Auth::user()->id doesn't work here when it does normally?

Sam
  • 887
  • 1
  • 12
  • 27
  • You should use [View Composers](https://laravel.com/docs/5.7/views#sharing-data-with-all-views). `auth()->user()` won't be available in your constructor since it is trying to fetch this from session which is not available in constructors. – Mozammil Jan 10 '19 at 12:35

5 Answers5

0

Create a Base Controller which has all the information that you want to share too all controllers/pages/views and let your others controllers extend it.

CritingZ
  • 388
  • 2
  • 16
  • 1
    If you re-read my question, that is exactly what I'm doing and what the linked answer suggests. The problem is that the information I want to share doesn't seem to be available to the BaseController. – Sam Jan 10 '19 at 12:44
  • I just saw it. Try to do it not in the __construct and see if it works. __construct is loaded before all other things and it's possible to be because of that. – CritingZ Jan 10 '19 at 12:53
  • Problem is though, I need the function to run automatically for every page load. Is that possible if I put the code in some other function I create? – Sam Jan 10 '19 at 12:57
  • I think somewhere I used a code just like Abdullah Al Shakib commented here in the last comment. – CritingZ Jan 10 '19 at 13:02
0

open file AppServiceProvider.php from folder Providers and write below code in boot function

     view()->composer('*', function ($view)
    {
        $view->with('cartItem', $cart );

    });

And now go to your view page and write :

{{ $cartItem }}
  • $view->with('cartItem', $cart ); in this line $cart will be replaced by your data which you want to share to all your view – Risheekant Vishwakarma Jan 10 '19 at 12:47
  • This worked for a simple typed-in variable but I still couldn't use `Auth::user()->id` to get the current user ID. I added `use Auth` and `use DB` so I could run my query to get the information but then got a big error about Symfony framework stuff – Sam Jan 10 '19 at 12:55
  • you can use everything just check my second answer – Risheekant Vishwakarma Jan 10 '19 at 12:59
0

You cannot access Auth in constructors because middleware has not been run yet. You can use either View composer or give try this way though i haven't tested.

class BaseController extends Controller {
    protected $userId;

    public function __construct() {
        $this->middleware(function ($request, $next) {
           $this->userId= Auth::user()->id;

           return $next($request);
        });
    }
}
Abdullah Al Shakib
  • 2,034
  • 2
  • 15
  • 16
  • Presumably then I'd just use `$userId` instead of `Auth::user()->id`? I tried doing it but got undefined variable error – Sam Jan 10 '19 at 12:53
0

Write this in AppServiceProvider.php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Schema;
use DB;
use Auth;
use App\Cart;

class AppServiceProvider extends ServiceProvider
{

    public function boot()
    {
        Schema::defaultStringLength(191);

            view()->composer('*', function ($view)
            {

                view()->composer('*', function($view)
                {
                    if (Auth::check()) {
                        $cart = Cart::where('user_id', Auth::user()->user_id)->count();
                        $view->with('cartItem', $cart );
                    }else {
                        $view->with('cartItem', 0);
                    }
                });


            });

    }


}

In you view simply write

{{ $cartItem }}
  • This doesn't seem to work but I did have to edit it because I don't have cart, and maybe my replacement is what broke it. Do you have a non-cart example, something that all Laravel installs contain? – Sam Jan 10 '19 at 13:13
0

For anyone interested, I just encountered the same problem and I've solved it with ServiceProvider:

  1. Define your custom ServiceProvider with the command
php artisan make:provider CustomServiceProvider
  1. Add a reference to your service provider in the config\app.php file, specifically in the providers array, adding this item to it:
\App\Providers\CustomServiceProvider::class,
  1. Declare the variables you want to share in your provider's boot() method and share them by using the view()->share method:
public function boot()
{
    $shared_variable = "Hello";

    view()->share('shared_variable', $shared_variable); 
}
  1. You can now reference your variable in your blade files with the standard notation:
{{ $shared_variable }}
lpizzinidev
  • 12,741
  • 2
  • 10
  • 29