livewire: Getting an error when trying to load a livewire modal with form component

Introduction

I’m creating a crud functionality within the livewire stack. I’m getting the following error when I am trying to load the create.blade.php component as modal using alpine.js. Its working perfectly when I use @include('livewire.user-base.user.create') but it ain’t working and throwing a set of error when trying to load the same thing as a livewire component using <livewire:user-base.user.create /> .

Error Which I’m Getting In The Console

Uncaught (in promise) TypeError: Cannot read property 'replace' of null
    at alpinifyElementsForMorphdom (SupportAlpine.js:143)
    at onBeforeElUpdated (index.js:461)
    at callHook (morphdom.js:35)
    at morphEl (morphdom.js:199)
    at morphdom.js:463
    at Component.value (index.js:368)
    at Component.value (index.js:277)
    at Component.value (index.js:248)
    at Connection.value (index.js:7)
    at index.js:50

Livewire Error

Source Code

  • Index.php
<?php

namespace App\Http\Livewire\UserBase\User;

use Livewire\Component;
use Livewire\WithPagination;
use App\Models\User;
use App\Models\Role;

class Index extends Component
{
    use WithPagination;

    public function render()
    {
        $users = User::latest()->paginate(5);
        return view('livewire.user-base.user.index', ['users' => $users]);
    }

    public function edit($id) 
    {
        $users = User::findOrFail($id);
        return redirect()->route('user.edit', compact('id'));
    }

    public function delete($id)
    {
        $users = User::findOrFail($id);
        $users->Roles()->detach();
        $users->delete();
        session()->flash('delete','User Deleted Successfully');
    }
}
  • Create.php
<?php

namespace App\Http\Livewire\UserBase\User;

use Livewire\Component;
use App\Models\User;
use App\Models\Role;
use Illuminate\Support\Facades\Hash;

class Create extends Component
{
    public $name;
    public $email;
    public $password;
    public $role;

    public function render()
    {   
        $roles = Role::all();
        return view('livewire.user-base.user.create', ['roles' => $roles]);
    }

    public function store()
    {
        $this->validate(
            [
                'name' => 'required|string|max:255',
                'email' => 'required|string|email|max:255|unique:users',
                'password' => 'required|string',
                'role' => 'required'
            ]
        );

        $user = User::create([
            'name' => $this->name,
            'email' => $this->email,
            'password' => Hash::make($this->password)
        ]);

        $user->Roles()->sync($this->role);

        session()->flash('success', 'User Created Successfully');
    }

    public function cancel()
    {
        return redirect()->route('user.index');
    }
}
  • index.blade.php
<x-slot name="header">
    <h2 class="text-xl font-semibold leading-tight text-gray-800">
        Manage User
    </h2>
</x-slot>

<div>
    <div class="py-12">
        <div class="mx-auto max-w-5xl px-6 lg:px-8">

        <div x-data="{ open: false }">
            <button @click="open = true" class="inline-flex justify-center w-20 rounded-md border border-gray-300 px-4 py-2 bg-gray-200 font-medium text-gray-700 shadow-sm hover:text-gray-500 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue transition ease-in-out duration-150 text-sm leading-5">Create</button>
            <livewire:user-base.user.create />
        </div>

            @if(session()->has('success'))
            <div class="bg-green-200 border border-green-400 rounded-lg mb-8 px-6 py-4">
                <div>
                    <h1 class="text-green-500 text-sm leading-5">{{ session('success') }}</h1>
                </div>
            </div>
            @endif

            @if(session()->has('delete'))
            <div class="bg-red-200 border border-red-400 rounded-lg mb-8 px-6 py-4">
                <div>
                    <h1 class="text-red-500 text-sm leading-5">{{ session('delete') }}</h1>
                </div>
            </div>
            @endif

            <div class="flex flex-col">
                <div class="-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
                    <div class="py-2 align-middle inline-block min-w-full sm:px-6 lg:px-8">
                        <div class="shadow overflow-hidden border-b border-gray-200 rounded-lg">
                            <table class="min-w-full divide-y divide-gray-200">
                                <thead>
                                    <tr>
                                        <th class="px-6 py-3 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
                                            ID
                                        </th>
                                        <th class="px-6 py-3 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
                                            Name
                                        </th>
                                        <th class="px-6 py-3 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
                                            Email
                                        </th>
                                        <th class="px-6 py-3 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
                                            Account Type
                                        </th>
                                        <th class="px-6 py-3 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
                                            Creation
                                        </th>
                                        <th class="px-6 py-3 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
                                        </th>
                                    </tr>
                                </thead>
                                <tbody class="bg-white divide-y divide-gray-200">
                                    @foreach($users as $key=>$user)
                                    <tr>
                                        <td class="px-6 py-4 whitespace-no-wrap">
                                            <div class="text-sm leading-5 text-gray-900">
                                                {{ $users->firstitem() + $key }}
                                            </div>
                                        </td>
                                        <td class="px-6 py-4 whitespace-no-wrap">
                                            <div class="text-sm leading-5 text-gray-900">
                                                {{ $user->name }}
                                            </div>
                                        </td>
                                        <td class="px-6 py-4 whitespace-no-wrap">
                                            <div class="text-sm leading-5 text-gray-900">
                                                {{ $user->email }}
                                            </div>
                                        </td>
                                        <td class="px-6 py-4 whitespace-no-wrap">
                                            <div class="text-sm leading-5 text-gray-900">
                                                @foreach($user->Roles as $role)
                                                    {{ $role->name }}
                                                @endforeach
                                            </div>
                                        </td>
                                        <td class="px-6 py-4 whitespace-no-wrap">
                                            <div class="text-sm leading-5 text-gray-900">
                                                {{ $user->created_at->format('d-m-y') }}
                                            </div>
                                        </td>
                                        <td class="px-6 py-4 whitespace-no-wrap text-right text-sm leading-5 font-medium">
                                            <button wire:click="show({{ $user->id }})" class="text-indigo-600 hover:text-indigo-900">
                                                View
                                            </button>
                                            <button wire:click="edit({{ $user->id }})" class="text-indigo-600 hover:text-indigo-900">
                                                Edit
                                            </button>
                                            <button wire:click="delete({{ $user->id }})" class="text-indigo-600 hover:text-indigo-900">
                                                Delete
                                            </button>
                                        </td>
                                    </tr>
                                    @endforeach
                                </tbody>
                            </table>
                        </div>
                    </div>
                </div>
            </div>
            <div class="mt-4">
                {{$users->links()}}
            </div>
        </div>
    </div>
</div>
  • create.blade.php
<div x-cloak x-show="open" class="fixed z-10 inset-0 overflow-y-auto">
    <div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">

        <div x-show="open" x-transition:enter="ease-out duration-300" x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100" x-transition:leave="ease-in duration-200" x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0" class="fixed inset-0 transition-opacity">
            <div class="absolute inset-0 bg-gray-500 opacity-75"></div>
        </div>

        <span class="hidden sm:inline-block sm:align-middle sm:h-screen"></span>

        <div x-show="open" x-transition:enter="ease-out duration-300" x-transition:enter-start="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95" x-transition:enter-end="opacity-100 translate-y-0 sm:scale-100" x-transition:leave="ease-in duration-200" x-transition:leave-start="opacity-100 translate-y-0 sm:scale-100" x-transition:leave-end="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95" class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full" role="dialog" aria-modal="true" aria-labelledby="modal-headline">

            <div class="shadow overflow-hidden sm:rounded-md">

                <div class="px-4 py-5 bg-white sm:p-6">
                    <div class="grid grid-cols-6 gap-6">
                        <div class="col-span-6">
                            <label for="name" class="block text-sm font-medium leading-5 text-gray-700">Name</label>
                            <input wire:model="name" class="mt-1 form-input block w-full transition duration-150 ease-in-out sm:text-sm sm:leading-5">
                            @error('name') <h1 class="text-sm font-medium leading-5 text-red-400 py-2">{{$message}}</h1>@enderror
                        </div>
                        <div class="col-span-6">
                            <label for="email" class="block text-sm font-medium leading-5 text-gray-700">Email</label>
                            <input wire:model="email" class="mt-1 form-input block w-full transition duration-150 ease-in-out sm:text-sm sm:leading-5">
                            @error('email') <h1 class="text-sm font-medium leading-5 text-red-400 py-2">{{$message}}</h1>@enderror
                        </div>
                        <div class="col-span-6">
                            <label for="password" class="block text-sm font-medium leading-5 text-gray-700">Password</label>
                            <input wire:model="password" class="mt-1 form-input block w-full transition duration-150 ease-in-out sm:text-sm sm:leading-5">
                            @error('password') <h1 class="text-sm font-medium leading-5 text-red-400 py-2">{{$message}}</h1>@enderror
                        </div>
                        <div class="col-span-6">
                            <label for="role" class="block text-sm font-medium leading-5 text-gray-700">Role</label>
                            <select wire:model="role" class="mt-1 form-select block w-full transition duration-150 ease-in-out sm:text-sm sm:leading-5">
                                <option value=""></option>
                                @foreach($roles as $role)
                                <option value="{{ $role->id }}">{{ $role->name }}</option>
                                @endforeach
                                @error('role') <h1 class="text-red-500">{{$message}}</h1>@enderror
                            </select>
                            @error('role') <h1 class="text-sm font-medium leading-5 text-red-400 py-2">{{$message}}</h1>@enderror
                        </div>
                    </div>
                </div>

                <div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
                    <span class="flex w-full rounded-md shadow-sm sm:ml-3 sm:w-auto">
                        <button wire:click.prevent="store()" type="button" class="inline-flex justify-center w-full rounded-md border border-transparent px-4 py-2 bg-red-600 text-base leading-6 font-medium text-white shadow-sm hover:bg-red-500 focus:outline-none focus:border-red-700 focus:shadow-outline-red transition ease-in-out duration-150 sm:text-sm sm:leading-5">
                            Create
                        </button>
                    </span>
                    <span class="mt-3 flex w-full rounded-md shadow-sm sm:mt-0 sm:w-auto">
                        <button @click="open = false" type="button" class="inline-flex justify-center w-full rounded-md border border-gray-300 px-4 py-2 bg-white text-base leading-6 font-medium text-gray-700 shadow-sm hover:text-gray-500 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue transition ease-in-out duration-150 sm:text-sm sm:leading-5">
                            Cancel
                        </button>
                    </span>
                </div>

            </div>

        </div>

    </div>
</div>

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 21 (5 by maintainers)

Most upvoted comments

Way to go! Thanks for that.

Hello, people,

I have been facing similar issues.

Basically, the problem is that Livewire (through Alpine.js), is trying to remove a style attribute from the element, but the element does not have any style attribute originally.

Now, you can manually just add a style attribute to your component and avoid the error, appearing. BUT this would not probably resolve your issues in general.

Based on my recent experience, it is not a good idea to create a Livewire component for only a modal (or anything with a dynamic display property). Instead, try to “attach” the component to a more generic element that does not apply the x-show directive on it directly.

I hope it makes sense to some of you.

PS: Alternatively, you can try to use the @entangle directive of alpine, to synchronize the visualization or a component across Livewire and Alpine.js.