modal icon indicating copy to clipboard operation
modal copied to clipboard

Undefined array key 1 when opening from function

Open MrMooky opened this issue 4 years ago • 7 comments

I'm opening a modal from a function on page load if a condition is met.

Blade template:

@if ($user->subscription?->latest_webhook == 'waiting')
    @push('scripts')
        <script>
            setTimeout(function() {
                Livewire.emit('openModal', 'subscription-webhook-status');
            }, 800);
        </script>
    @endpush
@endif

This, sometimes, results in the following error:

Undefined array key 1 (View: /resources/views/vendor/livewire-ui-modal/modal.blade.php)

The highlighted error is within the file vendor/livewire/livewire/src/LivewireManager.php:399, the return $matches[1][0];.

public function getRootElementTagName($dom)
{
    preg_match('/<([a-zA-Z0-9\-]*)/', $dom, $matches, PREG_OFFSET_CAPTURE);
 
    return $matches[1][0];
}

Livewire, Wire Elements Modal and AlpineJS are using the latest version. Any idea what is causing this problem?

MrMooky avatar Dec 22 '21 11:12 MrMooky

Did you make any changes to modal.blade.php? Also, how does the blade view look like for the 'subscription-webhook-status' modal?

PhiloNL avatar Dec 22 '21 13:12 PhiloNL

Yes, I edited the modal.blade.php.

I removed the close button: <span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">&#8203;</span>

I also changed a few classes and removed x-on:click="closeModalOnClickAway()". Other than that, nothing changed.

This is the subscription-webhook-status template:

<div wire:poll.5000ms>
    <x-modal>
        <x-slot name="title">
            Please wait ...
        </x-slot>
    
        <x-slot name="content">
            <p>Your subscription will be updated in a few seconds. You should be redirected ...</p>
        </x-slot>
    
        <x-slot name="buttons">
            <div class="flex-1">
                <span class="animate-spin spinner__inline"></span>
            </div>

            <div class="pl-5">
                <a href="{{ route('subscription') }}" class="btn">
                    Refresh
                </a>
            </div>
        </x-slot>
    </x-modal>
</div>

When I type Livewire.emit('openModal', 'subscription-webhook-status') into the browser console, it works just fine. There is no dynamic stuff happening from my side. I just have a condition about the webhook status (latest_webhook from my initial question) and if that is set, I fire the function after 800ms.

This is my current modal.blade.php. It works very well so far, except for that one issue:

<div>
    @isset($jsPath)
        <script>{!! file_get_contents($jsPath) !!}</script>
    @endisset
    @isset($cssPath)
        <style>{!! file_get_contents($cssPath) !!}</style>
    @endisset

    <div
            x-data="LivewireUIModal()"
            x-init="init()"
            x-on:close.stop="show = false"
            x-on:keydown.escape.window="closeModalOnEscape()"
            x-on:keydown.tab.prevent="$event.shiftKey || nextFocusable().focus()"
            x-on:keydown.shift.tab.prevent="prevFocusable().focus()"
            x-show="show"
            class="fixed inset-0 z-10 overflow-y-auto"
            style="display: none;"
    >
        <div class="flex items-center justify-center min-h-screen text-center bg-bodyText/50">
            <div
                    x-show="show && showActiveComponent"
                    x-transition:enter="ease-out duration-300"
                    x-transition:enter-start="opacity-0 translate-y-4 translate-y-0 scale-95"
                    x-transition:enter-end="opacity-100 translate-y-0 scale-100"
                    x-transition:leave="ease-in duration-200"
                    x-transition:leave-start="opacity-100 translate-y-0 scale-100"
                    x-transition:leave-end="opacity-0 translate-y-4 translate-y-0 scale-95"
                    x-bind:class="modalWidth"
                    class="inline-block w-full align-center px-5 pt-5 bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all m-3"
            >
                @forelse($components as $id => $component)
                    <div x-show.immediate="activeComponent == '{{ $id }}'" x-ref="{{ $id }}" wire:key="{{ $id }}">
                        @livewire($component['name'], $component['attributes'], key($id))
                    </div>
                @empty
                @endforelse
            </div>
        </div>
    </div>
</div>

MrMooky avatar Dec 22 '21 13:12 MrMooky

Does the error only occur when polling? If this is the case, have you tried to move wire:poll.5000ms to a different element?

PhiloNL avatar Dec 28 '21 17:12 PhiloNL

I just removed the polling declaration and the error still occurs. When logging return $matches[1][0] in vendor/livewire/livewire/src/LivewireManager.php:399, I get this:

Screenshot 2021-12-29 at 09 22 46

I'm aware that this is coming from the Livewire source, but it is definitely related to the modal package.

I also directly moved the script inline (no @push or anything) and removed the timeout. Same issue. But it still works fine when manually reloading the page. This is really odd. 🤔

@if ($user->subscription?->latest_webhook == 'waiting')
    <script>
        Livewire.emit('openModal', 'subscription-webhook-status');
    </script>
@endif

MrMooky avatar Dec 29 '21 08:12 MrMooky

I just stumbled upon the same error, but in a different context:

$this->domain = Domain::where('id', $domain_id)->first();

if (! $this->domain) {
    return redirect(route('settings.domain'))->with('error', 'Domain was not found');
}

So if $this->domain does not exist and I want to redirect, the same error as mentioned in my initial issue appears.

MrMooky avatar Dec 30 '21 11:12 MrMooky

A repository with a fresh install of Laravel and Livewire replicating this problem would be helpful; it's difficult to diagnose without the actual code.

PhiloNL avatar Dec 30 '21 12:12 PhiloNL

There you go: https://github.com/MrMooky/wire-elements-error

The conditions in my app are a bit different, though. But you still see the problem when opening the modal.

MrMooky avatar Dec 31 '21 07:12 MrMooky