Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

stanhook's avatar

Reuse Data from a Controller in an other View

Hi,

I am new at this and need a little help.

I have a view that contains data in a sidebar. The view has a controller and the information in that sidebar is populated from a query in that controller. I now want to create other views each with their own controller but keep that sidebar. I was thinking of using a partial but I didn't know if that would work or if I could create a controller just for a partial or if either was a best practice. I didn't want to just repeat the query in each controller.

Each below is a query I need to use in the other controllers:

return view( 'ResearchReports.ResearchDatabase.explore.explore_maps' )
             ->with( 'site', $site )
             ->with( 'studyUnits', $studyUnits )
             ->with( 'selectStructures', $selectStructures )
             ->with( 'excavations', $excavations );

I have an ID in the URL that is needed for each of these queries.

I basically want to reuse that query in multiple controllers so I can populate that sidebar for all the other views without copy/paste the query in each controller..

Thanks, Stan

0 likes
16 replies
jlrdw's avatar

Perhaps cache the results. Or put that query in a class you can call when needed.

tykus's avatar

I was thinking of using a partial but I didn't know if that would work or if I could create a controller just for a partial or if either was a best practice

There is definitely a call for a partial (or View Component) to represent the sidebar in this case. Think about maintenance; if you needed to modify the sidebar, you want to do that task in one place only, not across multiple views.

As far as gathering the data for that view partial/component, it depends on which approach you decide to take

(i) View Partial

You can define a View Composer to organise the data needed for that view template. If the data is slowly changing, then choosing a caching strategy might become necessary when your application becomes moderately heavily used.

(ii) View Component

If you choose to use a View Component instead, you can now have a specific class that is responsible for organising that data, and rendering the sidebar view. Same advice regarding caching applies.

Personally, I would choose Blade Components in a similar scenario.

stanhook's avatar

I chose to create a Service class with the queries that I can call in any controller. Thought's?

JussiMannisto's avatar

One approach is to use View::share() to share data with all views.The docs show it done in a service provider, but I'd do it in a middleware. That way you're not running unnecessary queries during artisan commands or API calls, for example. And you can apply that middleware on just the routes that need it.

tykus's avatar

@JussiMannisto the data is just needed in a single sidebar view template, so View::share is not appropriate.

@stanhook I don’t understand; do you need exactly the same data for the sidebar as the main page content???

stanhook's avatar
stanhook
OP
Best Answer
Level 1

@tykus Yes. Exactly the same data in a number of views. It is general information that I want available in a number of views with text and links. I created a Service Class, placed all my queries in there and used that.

tykus's avatar

@stanhook something about this smells... but I don't know your application, or the full problem you are trying to solve. Is the same data needed on multiple pages because it is in a shared partial/component (e.g. a header, sidebar or footer), or are there multiple pages with duplicated information?

stanhook's avatar

@tykus Think of this as a house. The main page is the floor plan and in the sidebar there is information (text and links) about the house - home details, specs, links to various other specs, associated builder information, links to that particular construction data, lot locations, etc. All of which is pulled from the database that is related to that floor plan.. As the user navigates to any of those other sections, I need that sidebar information to stay so the user can continue to review other information about that floor plan.

Does that help?

tykus's avatar

@stanhook I'm not sure it does help TBH.

The sidebar is a list of (current floor plan-specific) links, or is something more like the main content? Why does the Controller actions need to fetch this exact data as well as say a Sidebar Component class?

If the structure of the data is exactly the same in both cases, then something about your solution would seem sub-optimal.

stanhook's avatar

@tykus Maybe this helps. The user can choose many different locations from a map and then the floor plans that are available for that location get populated on another map. From there they can choose a floor plan that populates the main area of content as well as various features as mentioned in the sidebar. It is possible though, that they can navigate to a section of the floor plan that will populate a new set of data in that sidebar.

Before the user would have to use forms and make their selections of specific options in order to see that floor plan specific data, content that would populate the main content area. We are just making that data available in the sidebar so the user doesn't have to go through all of those steps just to get a single piece of information. We are making all of the information available in that sidebar as long as it is relative to what they are currently viewing. If the move to a different area of the floor plan or location it is possible that the sidebar gets populated with something else from the database.

If I can do that with a Sidebar Component can you explain more why (how) that would be better than the Service Class that I created?

Just to note, the Service Class works great can provides what I need.

Thanks for the help.

tykus's avatar

@stanhook I don't doubt the Service class can do the job... you don't seem to understand what I am saying about the need for the same data being required across multiple Controller actions and the sidebar ¯\_(ツ)_/¯

stanhook's avatar

@Snapey I can take a look at that. Is creating a Service Class and placing my queries in there not a good idea?

Snapey's avatar

@stanhook it can be done, but it would be a bit pointless since it still does not give you what you want

martinbean's avatar

@stanhook Why do you keep going on about service classes when you’ve been told multiple times now to use a view composer?

If you have a common element such as a sidebar that will be present on multiple pages, extract the mark-up to a partial, and include that partial in the pages that need it:

<main>
    <!-- Main page content -->
</main>
@include('partials.sidebar')

Then create a view composer to give that partial the data it needs:

use Illuminate\Contracts\View\View;

class SidebarComposer
{
    protected FooService $foo;
    protected BarService $bar;

    public function __construct(FooService $foo, BarService $bar)
    {
        $this->foo = $foo;
        $this->bar = $bar;
    }

    public function compose(View $view)
    {
        $view->with([
            'foo' => $this->foo->someMethod(),
            'bar' => $this->bar->someMethod(),
        ]);
    }
}

Then you need to associate the view composer with the Blade template. You’d do this in a service provider’s boot method. You can just do it in your existing AppServiceProvider class:

use App\View\Composers\SidebarComposer;
use Illuminate\Support\Facades\View;

class AppServiceProvider extends Provider
{
    public function boot()
    {
        View::composer('partials.sidebar', SidebarComposer::class);
    }
}
stanhook's avatar

Thanks for the help! I will try to see about View Composer. I didn't realize that is the suggested method and I didn't quite understand it. I was just asking again about the Service Class because it is working exactly how I want and I wanted to know why I shouldn't do it that way.

Thanks again for the help and pointing me into the right direction and I will try to get it working that way.

Please or to participate in this conversation.