jcc5018's avatar

Livewire Datatable problem with eager loaded relations.

I am looking into a livewire version of datatables due to the normal version docs being out of date to try and follow. I was going through the video instructions on the livewire site, but its not working out due to the relationships. I also need to include search functionality.

I am getting hung up with pagination when i try to eager load relationships. I've read that you can't pass collections, but I'm not entirely sure what to do to fix this.

<?php

namespace App\Http\Livewire\Hobby;

use App\Models\Hobby;
use App\Models\HobbyAltName;
use App\Models\Tag;
use Livewire\Component;
use Livewire\WithPagination;

class HobbyManager extends Component
{
    use WithPagination;

    public    $searchHobbies   = '';
    public    $hobbies;
    public    $categories;
    protected $paginationTheme = 'bootstrap';

    public function updatingSearch()
    {
        $this->resetPage();
    }

    public function mount()
    {
        $this->categories = Tag::withCount('hobbies')->whereTag_type('1')->get();
        $this->hobbies = Hobby::with('equipment', 'categories', 'hobbyAltNames', 'hobbyType', 'users')->get();
    }

    public function render()
    {

        $searchHobbies = '%' . $this->searchHobbies . '%';
//Search should search Altnames and hobby_names to display relative hobbies. 
        // $this->hobbies = Hobby::where('hobby_name', 'like', $searchHobbies)->get();
        //$this->AltNames = HobbyAltName::where('name', 'like', $searchHobbies)->get();


        // $this->hobbies = Hobby::where('hobby_name', 'like', $searchHobbies)->paginate(25);
      
        return view('livewire.hobby.hobby-manager', ['hobbies' => $this->hobbies->where('hobby_name', 'like', $searchHobbies)
            ->paginate(25), 'categories' => $this->categories]);
    }
}

LW Blade:

<div class="row">
    {{--    Search hobbies/ altname--}}
    <div class="col-md-4 mb-2">
             <label for="hobbies">Hobbies</label>
        <input type="text" wire:model="searchHobbies"/>


    </div>
</div>


<div class="container">
    <table class=" table table-bordered table-striped table-hover  table-responsive ajaxTable datatable
    datatable-Hobby">
        <thead class="thead-inverse">
            <tr>
                <th></th>
                <th>Hobby</th>
                <th>Alt Names</th>
                <th>Status</th>
                <th>Category</th>
                <th>Types</th>
                <th>Date Updated</th>
                <th>Likes</th>
                <th>Equipment</th>
                <th>Actionables</th>
            </tr>
        </thead>
        <tbody>

            @forelse($hobbies as $hobby)

                <tr>
                    <td></td>
                    <td><a href="{{route('hobbies.show', $hobby->id)}}">{{$hobby->hobby_name}}</a></td>
                    <td>@foreach( $hobby->hobbyAltNames as $name)
                            {{$name->name}}<br/>
                        @endforeach</td>
                    <td> {{ App\Models\Hobby::STATUS_RADIO[$hobby->status] ?? '' }}
                    </td>


                    <td>@foreach($hobby->categories as $cat)

                            @if($cat->parent_id != null)
                                {{ $categories->find($cat->parent_id)->tag ."/" }}
                            @endif
                            {{$cat->tag}}<br/>
                        @endforeach
                    </td>
                    <td>##</td>
                    <td>{{$hobby->updated_at->toFormattedDateString()}}</td>
                    <td>{{$hobby->users->count()}}</td>
                    <td> @include('admin.content.hobbies.equipment')</td>
                    {{-- <td>{{$hobby->equipment_count}}</td> --}}
                    {{-- <td>@include('admin.content.partials.demographics')</td> --}}
                    <td>{{$hobby->equipment->count()==0 ? 'Add Equipment':''}}
                        {{-- {{$hobby->profileImage->count()==0 ? 'Add Profile Image':''}} --}}


                    </td>
                </tr>
            @empty
                <tr class="span-10">No Records</tr>

            @endforelse
        </tbody>
    </table>
    <div>
        {{$hobbies->links()}}
    </div>

</div>

In addition to this, there will be tabs that show additional data per row so instead of one large table that i have to scroll horizontally, a tab will switch to other data sets of additional related data while keeping the same pagination location.

0 likes
4 replies
jcc5018's avatar

@Snapey well, it's not working at all with pagination. Get the common issue posed on every other forum about not accepting collections or something to do with JS.

Not in front of computer at the moment to post exact error

If I remove the pagination part, the data loads but the search doesn't filter the records. Though I do notice that the debug bar records are being changed for models loaded, but the actual rendering does not change. So not sure what's going on with that.

I would just try normal data tables but the docs havent been updated since laravel 5 something so trying to figure out what I need to change/add for my data probably isn't gonna go well either.

Ultimately I'm just getting frustrated. So many things to figure out. And when you rely on packages to save time, they don't work when they aren't documented properly or I have things set up just a tad differently (most likely due to inexperience) and they never work right.

Or tutorials/ packages insist on tailwinds or components which may be ok for some but just add another layer of complexity to what I'm already struggling to learn. Sometimes I can figure out the alternative bootstrap or non component way, other times it just makes the tutorials not usable.

jcc5018's avatar
jcc5018
OP
Best Answer
Level 8

Ok, just wrote a reply then refreshed the wrong screen... so here goes again.

I was following the livewire video on the site for pagination, so it worked fine until i tried to eager load relations to get rid of the n+1 issue.

so I have tried various combinations of including the variable, including mount, putting the call in the render field vs the return view, etc. Now its very possible and likely that i may not be formatting something correctly. I did manage to get my search to work just now, by adding the class="form-control" in my blade file, but the pagination was still off. I either had the error, or the pagination would show but wouldn't be clickable.

EDIT: ok, I'm thinking that perhaps that form control issue may have been blocking the pagination functionality also, cause right now it seems to work.

here is current code

<?php

namespace App\Http\Livewire\Hobby;

use App\Models\Hobby;
use App\Models\HobbyAltName;
use App\Models\Tag;
use Livewire\Component;
use Livewire\WithPagination;

class HobbyManager extends Component
{
    use WithPagination;

    public $searchHobbies = '';
    //public    $hobbies;
    public    $categories;
    protected $paginationTheme = 'bootstrap';

    public function updatingSearch()
    {
        $this->resetPage();
    }

    public function mount()
    {
        $this->categories = Tag::withCount('hobbies')->whereTag_type('1')->get();
        //$this->hobbies = Hobby::with('equipment', 'categories', 'hobbyAltNames', 'hobbyType', 'users')->get();
    }

    public function render()
    {

        $searchHobbies = '%' . $this->searchHobbies . '%';
        // $this->hobbies = Hobby::where('hobby_name', 'like', $searchHobbies)->get();
        //$this->AltNames = HobbyAltName::where('name', 'like', $searchHobbies)->get();
        $hobbies = Hobby::with('equipment', 'categories', 'hobbyAltNames', 'hobbyType')->withCount('users')->where('hobby_name', 'like',
                                                                                                                   $searchHobbies)->paginate(25);

        //->
        return view('livewire.hobby.hobby-manager', compact('hobbies'
        ));
    }
}

Please or to participate in this conversation.