0

I'm writing a web app using Laravel 5.6. I need a list of all the connections the current session user have, in all the views. I tried something like this

View::share('connections', Connection::getList(Auth::id()))

I put this code inside the boot function of AppServiceProvider. But the problem arises when the user isn't already logged in, because at that time Auth::id() is set to null.

The connection list is not generated when the user logs in. This throws the following error:

connections variable is not defined.

Tushar Bhatt
  • 15
  • 1
  • 11
  • Why don't you check `Auth::id()` first, and if it's `null`, initialise `connections` to a default value? – fubar Apr 05 '18 at 02:44
  • @fubar no, the problem is that the boot function is only being called once. So, connection list is not generated at log in. I've also tried moving this function inside the login controller. – Tushar Bhatt Apr 05 '18 at 02:47
  • 1
    Ah, I see. It needs to go somewhere that is called on every request. I typically put such code in a parent controller. Have you considered using a [ViewComposer](https://laravel.com/docs/5.6/views#view-composers)? – fubar Apr 05 '18 at 02:50
  • ^View composer is what you want – Kevin Pimentel Apr 05 '18 at 02:51
  • @fubar how do I use parent controller for this? – Tushar Bhatt Apr 05 '18 at 02:54
  • @SuperKevin I've tried with composer as well, the problem persists. – Tushar Bhatt Apr 05 '18 at 02:54
  • You extend all of your applications controllers by a given parent controller. And in the parent constructor, you call `View::share()`. And if a `ViewComposer` isn't working, you're likely doing something wrong. Post the code how you were using it, and we can try to help. – fubar Apr 05 '18 at 02:55

1 Answers1

2

This target can achieve through different method,

1. Using BaseController

The way I like to set things up, I make a BaseController class that extends Laravel’s own Controller, and set up various global things there. All other controllers then extend from BaseController rather than Laravel’s Controller.

class BaseController extends Controller
{
  public function __construct()
  {
    //its just a dummy data object.
    $user = User::all();

    // Sharing is caring
    View::share('user', $user);
  }
}

2. Using Filter

If you know for a fact that you want something set up for views on every request throughout the entire application, you can also do it via a filter that runs before the request — this is how I deal with the User object in Laravel.

App::before(function($request)
{
  // Set up global user object for views
  View::share('user', User::all());
});

OR

You can define your own filter

Route::filter('user-filter', function() {
    View::share('user', User::all());
});

and call it through simple filter calling.

Update According to Version 5.*

3. Using View Composer

View Composer also help to bind specific data to view in different ways. You can directly bind variable to specific view or to all views. For Example you can create your own directory to store your view composer file according to requirement. and these view composer file through Service provide interact with view.

View composer method can use different way, First example can look alike:

You could create an App\Http\ViewComposers directory.

Service Provider

namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class ViewComposerServiceProvider extends ServiceProvider {
    public function boot() {
        view()->composer("ViewName","App\Http\ViewComposers\TestViewComposer");
    }
}

After that, add this provider to config/app.php under "providers" section.

TestViewComposer

namespace App\Http\ViewComposers;

use Illuminate\Contracts\View\View;

class TestViewComposer {

    public function compose(View $view) {
        $view->with('ViewComposerTestVariable', "Calling with View Composer Provider");
    }
}

ViewName.blade.php

Here you are... {{$ViewComposerTestVariable}}

This method could help for only specific View. But if you want trigger ViewComposer to all views, we have to apply this single change to ServiceProvider.

namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class ViewComposerServiceProvider extends ServiceProvider {
    public function boot() {
        view()->composer('*',"App\Http\ViewComposers\TestViewComposer");
    }
}

Reference

Yogi
  • 609
  • 1
  • 8
  • 21