livewire / livewire

A full-stack framework for Laravel that takes the pain out of building dynamic UIs.
MIT License
22.35k stars 1.56k forks source link

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

Closed toxifiedmatrix closed 3 years ago

toxifiedmatrix commented 3 years ago

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

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

Manage User

@if(session()->has('success'))

{{ session('success') }}

@endif @if(session()->has('delete'))

{{ session('delete') }}

@endif
@foreach($users as $key=>$user) @endforeach
ID Name Email Account Type Creation
{{ $users->firstitem() + $key }}
{{ $user->name }}
{{ $user->email }}
@foreach($user->Roles as $role) {{ $role->name }} @endforeach
{{ $user->created_at->format('d-m-y') }}
{{$users->links()}}
- create.blade.php
XternalSoft commented 3 years ago

Hello,

I have same error.

  1. User form component
  2. Nested component (change password component)
  3. Error on validation fail in nested component

No problem with the main component all working

Livewire v2.3.2

toxifiedmatrix commented 3 years ago

I'm having this problem only after I use alpine, for the smooth modal based transitions along with the livewire create.blade.php component. I have no idea if there is something wrong on my part, or a bug in livewire.

XternalSoft commented 3 years ago

Same when I use AlpineJS (Interface with Tabs)

toxifiedmatrix commented 3 years ago

There are bugs or some sort of compatibility issues along with alpine.js when combined with livewire.

iksaku commented 3 years ago

Could you provide your Livewire and Alpine versions?

There are bugs or some sort of compatibility issues along with alpine.js when combined with livewire.

In the contrary, Alpine and Livewire are made to help one another, so, unless you're using incompatible versions of both of them, there shouldn't be any "lone" issues.

toxifiedmatrix commented 3 years ago

Livewire 2.3.2 AlpineJS 2.7.3

iksaku commented 3 years ago

Could you try removing the parenthesis when calling your create action?

-<button wire:click.prevent="create()">
+<button wire:click.prevent="create">
    Create
</button>
XternalSoft commented 3 years ago

It's happened when livewire try to change the DOM. And with a sub component

austenc commented 3 years ago

Hmm, this smells like another pesky morphDOM issue. @toxifiedmatrix do you think you could provide a github repo we could clone to reproduce this?

tpaksu commented 3 years ago

I'm currently having the same javascript exception, and it seems like something when you use both blade conditional display and alpine x-show together. If I understood correctly, alpine searches for the to-be-hidden element via x-show, and since it became hidden (removed from DOM) by blade already, it can't find it and throws that exception. And I'm not sure how I may fix this. Maybe something like re-initializing alpine when the DOM changes may work. But I'm not sure it'll be the best solution.

tpaksu commented 3 years ago

It's already there refreshAlpineAfterEveryLivewireRequest() on SupportAlpine.js:15, so I don't have anything to add :)

JuanDMeGon commented 3 years ago

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.

XternalSoft commented 3 years ago

Hello,

In my issue, I don't have modal or something else.

  1. One component for editing users table. In this interface there is "tab" managed with AlpineJS
  2. In tab, one sub livewire component with 2 input field for change user password. When editing input password ==> Javascript Error
kulasace04 commented 3 years ago

it worked in alpinejs v2.7.0 but the same error on the updated version of alpinejs

XternalSoft commented 3 years ago

Same issue with alpinejs v2.8.0

joshhanley commented 3 years ago

If someone can provide a sample repo that demonstrates the issue, I'd be happy to have a look at it, to work out what the bug is and see if we can get it resolved. πŸ™‚

JuanDMeGon commented 3 years ago

Hello @joshhanley,

I just created a branch in my repo.

Please, let me know if something else is needed.

Thanks and best wishes.

joshhanley commented 3 years ago

@JuanDMeGon thanks! I'll check it out πŸ™‚

joshhanley commented 3 years ago

I have PR'd a fix for this #2268.

Thanks @JuanDMeGon for the repo! It was very helpful!

JuanDMeGon commented 3 years ago

Way to go! Thanks for that.

squishythejellyfish commented 3 years ago

πŸ‘‹ Oh Hi! I'm Squishy, the friendly jellyfish that manages Livewire issues.

I see this issue has been closed.

Here in the Livewire repo, we have an "issues can be closed guilt-free and without explanation" policy.

If for ANY reason you think this issue hasn't been resolved, PLEASE feel empowered to re-open it.

Re-opening actually helps us track which issues are a priority.

Reply "REOPEN" to this comment and we'll happily re-open it for you!

(More info on this philosophy here: https://twitter.com/calebporzio/status/1321864801295978497)