Session flash message closes automatically on property reset
Greetings! I am using Laravel 11.29.0 with Livewire version 3.5 and AlpineJS version 3.14.3. I am currently in a pickle with Livewire session flash resetting on its own, a second after it is displayed on the page. The whole code that I will be presenting below are all in a single Livewire component. Basically, I have a Livewire action/method that edits multiple records as follows.
public function editSelected()
{
// Check if there is no selected category
if($this->selectedCategory == null)
{
/**
* Reset all variables
*/
$this->reset(['selectCurrentPage', 'selectAll', 'selectedRecords']);
session()->now('fail', 'Updated failed! No category was chosen for the bulk edit.');
return;
}
Post::whereIn('id', $this->selectedRecords)->update(['category_id' => $this->selectedCategory]); // Update the selected posts with the new category
$this->resetPage(); // Reset to page 1
$this->dispatch('hide-bulk'); // Hide the bulk dropdown
$this->selectedCategory = null;
session()->flash('success', 'Posts\' category successfully updated!');
}
Here is the modal button that triggers the action above.
<button wire:click="editSelected" x-on:click="show = false" type="button" class="px-5 py-2.5 me-2 text-sm font-medium text-white bg-sky-800 rounded-lg dark:bg-sky-600 dark:focus:ring-sky-900 dark:hover:bg-sky-700 focus:outline-none focus:ring-4 focus:ring-sky-300 hover:bg-sky-700">Update</button>
And here is where I display my flash message.
@if (session()->has('fail'))
<div wire:ignore wire:key="1" x-data="{ alertIsVisible: true }" x-show="alertIsVisible"
class = 'mb-4 overflow-hidden relative text-neutral-600 bg-white rounded-md border border-red-500 dark:text-neutral-300 dark:bg-neutral-950' role="alert" x-transition:leave="transition ease-in duration-300" x-transition:leave-start="opacity-100 scale-100" x-transition:leave-end="opacity-0 scale-90">
<div class="bg-red-500/10 w-full flex items-center gap-2 p-4">
<div class="bg-red-500/15 p-1 text-red-500 rounded-full" aria-hidden="true">
-- unimportant svg tag here --
</div>
<div class="ml-2">
<h3 class="text-sm font-semibold text-red-500">{{ session('fail') }}</h3>
</div>
<button type="button" x-on:click="alertIsVisible = false" class="ml-auto" aria-label="dismiss alert">
-- unimportant svg tag here --
</button>
</div>
</div>
@endif
After debugging, my findings is that the property reset and/or page reset actions in the code above are resetting the flash session data. If I remove this single line of code from the action above,
$this->reset(['selectCurrentPage', 'selectAll', 'selectedRecords']);
then the flash message will persist until the Livewire component is re-rendered or a page reload.
My tried solutions up until now are:
-
Using
session()->now('status', 'Task was successful!');, but the issue still persists. -
Using
session()->put('status', 'Task was successful!');, but then the session data will persist across requests (and not really an appropriate for flash messages). -
Use a 'errorMessage' property to store the flash messages, but that would not be appropriate as well.
-
Use the
wire:ignore. Also, usingx-ignoreis no-go since it will disabled my flash message that uses AlpineJS. -
Now, the properties to reset are Livewire entangled to their corresponding AlpineJS data. Iinstead of entangling the Livewire properties to AlpineJS data, I undo the entanglement. And so, I pass the AlpineJS data to the Livewire action on the button as follows:
<button x-on:click="show = false; $wire.editSelected(selectedRecords)" type="button" class="px-5 py-2.5 me-2 text-sm font-medium text-white bg-sky-800 rounded-lg dark:bg-sky-600 dark:focus:ring-sky-900 dark:hover:bg-sky-700 focus:outline-none focus:ring-4 focus:ring-sky-300 hover:bg-sky-700">Update</button>
Due to that change the invoked Livewire action is also modified as shown below.
public function editSelected(array $selected)
{
// Check if there is no selected category
if($this->selectedCategory == null)
{
session()->flash('fail', 'Updated failed! No category was chosen for the bulk edit.');
return;
}
$this->resetPage(); // Reset to page 1
$this->dispatch('hide-bulk'); // Hide the bulk dropdown
Post::whereIn('id', $selected)->update(['category_id' => $this->selectedCategory]); // Update the selected posts with the new category
$this->selectedCategory = null;
session()->flash('success', 'Posts\' category successfully updated!');
}
The reset for the selectedRecords, etc, are now done by dispatching an event through the $this->dispatch('hide-bulk') which refers to this line of code:
{{-- Bulk Dropdown START --}}
<div x-cloak x-show="bulkOpen" x-on:hide-bulk.window="bulkOpen = false; selectAll = false; selectCurrentPage = false; selectedRecords = []" x-on:click.outside="bulkOpen = false"
However, the same issue still occurs where session flash data will reset after a second of the flash message showing up.
After going through those solutions, I am not sure what else to try. I can provide more code, but I do not know if I should provide it here cause it will be too long, or should I just provide it in a reply of this discussion. Besides that, can somebody please explain to me why is AlpineJS interfering with the Livewire session flash? Thanks!
Update: Seems that a reset on the AlpineJS data whether by a dispatched event to directly reset the AlpineJS data OR from Livewire reset through wire.entangled property will cause a reset on the Livewire session flash.
Please or to participate in this conversation.