skip to Main Content

I have a "Route (Model)" which has many "PickupRequest".

I made a component that displays all components as two lines of text. However, if it’s the "currentRequest" (we go through each one one by one), I display another Livewire component.

In my modal, I want to sent the event to "RequestsList" in order to go to the next request and refresh the list to display the right request. The update is made in the DB, but the content of the page doesn’t change.

Here is my code:

List:

<?php

namespace AppHttpLivewireRoutes;

use AppModelsPickupRequest;
use AppModelsRoute;
use LivewireComponent;

class RequestsList extends Component
{
    public Route $route;
    public $requests;
    public PickupRequest $currentRequest;

    protected $listeners = ['nextRequest' => 'nextRequest'];

    public function mount() {
        $this->requests = $this->route->requestsWithDone;
    }

    public function booted() {
        $this->currentRequest = $this->route->requests()->first();
    }

    public function nextRequest() {
        $this->currentRequest = $this->route->requests()->first();
    }

    public function render()
    {
        return view('livewire.routes.requests-list');
    }
}
====
<div>
@livewire('routes.in-progress', ['request' => $currentRequest])

@foreach($requests as $request)
    @if($request->id != $currentRequest->id)
        <div class="overflow-hidden bg-white shadow sm:rounded-lg cursor-pointer mb-4" wire:key="r_{{ $request->id }}">
            <div class="px-4 py-5 sm:px-6">
                <h3 class="text-lg font-medium leading-6 text-gray-900">{{ $request->user->short_address }}
                    <p class="tw-badge {{ $request->status_color }}">{{ $request->status_text }}</p>
                </h3>
                <p class="mt-1 max-w-2xl text-sm text-gray-500">{{ $request->user->special_instructions }}</p>
            </div>
        </div>
   @endif
@endforeach
</div>

InProgress:

<?php

namespace AppHttpLivewireRoutes;

use AppModelsPickupRequest;
use AppModelsRoute;
use LivewireComponent;

class InProgress extends Component
{
    public PickupRequest $request;

    public function render()
    {
        return view('livewire.routes.in-progress');
    }
}
===
<div class="overflow-hidden bg-white shadow sm:rounded-lg mb-4" wire:key="ip_{{ $request->id }}">
    <div class="px-4 py-5 sm:px-6">
        <h3 class="text-lg font-medium leading-6 text-gray-900">{{ $request->user->short_address }}</h3>
        <p class="mt-1 max-w-2xl text-sm text-gray-500">{{ $request->user->special_instructions }}</p>
    </div>
    <div class="border-t border-gray-200 px-4 py-5 sm:px-6">
        <dl class="grid grid-cols-1 gap-x-4 gap-y-8 sm:grid-cols-2">
            <div class="sm:col-span-1">
                <dt class="text-sm font-medium text-gray-500">{{ __('routes.pickup.full_address') }}</dt>
                <dd class="mt-1 text-sm text-gray-900">{{ $request->user->full_address }}</dd>
            </div>
            <div class="sm:col-span-1">
                <dt class="text-sm font-medium text-gray-500">{{ __('routes.pickup.special_instructions') }}</dt>
                <dd class="mt-1 text-sm text-gray-900">{{ $request->user->special_instructions }}</dd>
            </div>
            <div class="sm:col-span-1">
                <dt class="text-sm font-medium text-gray-500">{{ __('routes.pickup.phone_number') }}</dt>
                <dd class="mt-1 text-sm text-gray-900">{{ $request->user->phone }}</dd>
            </div>
            <div class="sm:col-span-2">
                <dt class="text-sm font-medium text-gray-500">{{ __('routes.pickup.bags') }}</dt>
            </div>
            <div class="flex flex-row space-x-2 justify-end sm:col-span-2 flex-wrap">
                <x-button class="red-button hover:red-button mt-1"
                          wire:click="$emit('openModal', 'routes.modal.couldnt-pickup', {{ json_encode(['pickup_id' => $request->id]) }})">
                            {{ __('routes.pickup.cant_pickup') }}
                </x-button>
                <x-button class="mt-1">{{ __('routes.pickup.add_bag') }}</x-button>
                <x-button class="green-button mt-1">{{ __('routes.pickup.end') }}</x-button>
            </div>
        </dl>
    </div>
</div>

Modal (only PHP, the blade is irrelevant imo):

<?php

namespace AppHttpLivewireRoutesModal;

use AppModelsPickupRequest;
use IlluminateSupportFacadesGate;
use LivewireUIModalModalComponent;

class CouldntPickup extends ModalComponent
{
    public PickupRequest $pickup;

    public function mount($pickup_id)
    {
        $pickup = PickupRequest::findOrFail($pickup_id);

        Gate::authorize('update', $pickup);

        $this->pickup = $pickup;
    }

    public function update()
    {
        Gate::authorize('update', $this->pickup);

        if($this->pickup->is_active) {
            $this->pickup->couldnt_pickup_at = now();
            $this->pickup->save();
        }

        $this->emit('nextRequest');
        $this->closeModal();
    }


    public function render()
    {
        return view('livewire.routes.modal.couldnt-pickup');
    }
}

2

Answers


  1. Chosen as BEST ANSWER

    The key is supposed to be on the top elements in the parent Livewire component. The key shouldn't be set in the component file in InProgress.


  2. If the current livewire component is not directly the children of the recipient of the Emit event you are sending then you should use

    $this->emitUp('nextRequest');
    

    To refresh the whole component after you have made the request without reloading the page then you should use the magic function $refresh, the details can be found here, https://laravel-livewire.com/docs/2.x/actions#magic-actions

    protected $listeners = ['reloadContent' => '$refresh'];
    $this->emit('reloadContent');
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search