robsontenorio / mary

Laravel Blade UI Components for Livewire 3
https://mary-ui.com
Other
1.06k stars 136 forks source link

Uncaught Snapshot missing on Livewire component #441

Closed ibrahem-kamal closed 6 months ago

ibrahem-kamal commented 6 months ago

maryUI version

1.30.6

daisyUI version

latest

Livewire version

3.4

What browsers are affected?

Firefox, Chrome, Safari, Microsoft Edge

What happened?

first let me explain my use case . i have a modal that display a dropdown when the user select a shipping vendor (like dhl,fedex,etc..) and then the user can search countries and cities for that vendor .

i only add the select component if the user select a vendor so i have it like this

   @if($vendor)
        <livewire:reusable-components.vendor-country-select :$vendor :shippingType="'local'" :key="$vendor->id" />
    @endif

and thats the VendorCountrySelect class

class VendorCountrySelect extends Component
{
    public Vendor $vendor;

    // shipping type must be one of the following: 'international', 'local'
    public string $shippingType;

    public ?int $selectedCountry = null;

    public Collection $options;

    public function render()
    {
        return view('livewire.reusable-components.vendor-country-select');
    }

    public function mount(Vendor $vendor, string $shippingType)
    {
        $this->vendor = $vendor;
        $this->shippingType = $shippingType;
        if (!in_array($this->shippingType, ['international', 'local'])) {
            throw new \InvalidArgumentException('Invalid shipping type');
        }
        $this->search();
    }

    public function search(string $value = '')
    {
        $selectOption = null;
        if ($this->selectedCountry) {
            $selectOption = $this->vendor->countries()->find($this->selectedCountry);
        }
        $countriesResponse = app(ShippingService::class)
            ->setVendor($this->vendor)
            ->fetchCountries($value, limit: 10);
        if ($countriesResponse->isSuccess()) {
            $filteredOptions = $countriesResponse->getData('countries');
        } else {
            $filteredOptions = collect([]);
        }
        if ($selectOption) {
            $filteredOptions = $filteredOptions->merge([$selectOption]);
        }
        $this->options = $filteredOptions;
    }

and its view is just a simple blade with the following

@if($vendor)
    <div class="w-full">
        <x-mary-choices label="{{ __('إختر الدولة') }}"  :options="$options" wire:model="selectedCountry" single class="w-full" searchable min-chars="2" />
    </div>
@endif

now everything works fine at first . if select,uselect, anything but the second i start using search it filters and set the correct filtered options but then it throws in console this error

Uncaught Snapshot missing on Livewire component with id: IBGqjPr5Lh16DQfLBCBl

and after that it just freeze i cant do anything else . i will attach a video for that below

https://github.com/robsontenorio/mary/assets/38753243/b956cbf5-6598-4f7e-8657-cbe15ffcf38f

robsontenorio commented 6 months ago

I am afraid this is a Livewire question , not maryUI. Probably because there are nested components or some missing wire:key

Just replace the maryUI component for your own component and the issue will persist.

robsontenorio commented 6 months ago

See

https://github.com/robsontenorio/mary/issues/374#issuecomment-2050693826

ibrahem-kamal commented 6 months ago

actually it doesn't . changing the component with native select and repopulate the options doesn't throw this error . also adding wire:key didn't solve the issue. do you have any other ideas what would be causing that ?

@if($vendor)
    <div class="w-full">
        <x-mary-choices label="{{ __('إختر الدولة') }}"  :options="$options" wire:model="selectedCountry" single class="w-full" searchable min-chars="2" wire:key="{{$vendor->id}}" />
    </div>
@endif
ibrahem-kamal commented 6 months ago

@robsontenorio my apologies . adding the wire:key to the div itself and not the x-choices solved the issue for me . thanks for your help

<div class="w-full" wire:key="x">
    @if($vendor)
        <x-mary-choices label="{{ __('إختر الدولة') }}" :options="$options" wire:model="selectedCountry" single
                        class="w-full" searchable min-chars="2" />
    @endif
</div>