Power-Components / livewire-powergrid

⚡ PowerGrid generates modern, powerful and easy-to-customize data tables using Laravel Livewire.
https://livewire-powergrid.com
MIT License
1.5k stars 219 forks source link

[Bug]: When using blade header component, I get "Livewire encountered corrupt data" Error #1083

Closed abhaypithadiya closed 1 year ago

abhaypithadiya commented 1 year ago

Have you searched through other issues to see if your problem is already reported or has been fixed?

Yes, I did not find it.

Did you read the documentation?

Yes, I did not find it.

Have you tried to publish the views?

Yes - I didn't work.

Is there an error in the console?

No

PHP Version

8.1

PowerGrid

^4.8

Laravel

v10.17.1

Livewire

v2.12.5

Alpine JS

3.x.x

Theme

Bootstrap

Describe the bug.

I am using blade components in row action and header action, both the button has two different modals which pop up, when I click on the action button of the modal I get this error "Livewire encountered corrupt data when trying to hydrate the [admin.back-office-user.back-office-user-listing-table] component. Ensure that the [name, id, data] of the Livewire component wasn't tampered with between requests."


    public function actions(): array
    {
        return [
            Button::add('deleteButton')
                ->bladeComponent('delete_button', ['id' => 'id', 'name' => 'name']),
        ];
    }

    public function delete($id)
    {
        $result = BackOfficeUser::findOrFail($id)->delete();

        if ($result) {
            session()->flash('success', 'Back Office User Deleted Successfully!');
        } else {
            session()->flash('error', 'Database Error Occurred!');
        }

        return redirect(route('backOfficeUser.show'));
    }

    public function header(): array
    {
        return [
            Button::add('bulkDelete')
                ->bladeComponent('bulk_delete_button', ['name' => 'test']),
        ];
    }

    public function bulkDelete()
    {
        dd('test');
    }

if I remove the header button, everything works fine. How can i resolve this error?

To Reproduce...

First click on "FOO" then....

Extra information

<?php
 //...
luanfreitasdev commented 1 year ago

Hello!, can you share delete_button component ?

abhaypithadiya commented 1 year ago

Hello! this is my delete_button component.

<div>
  <span data-bs-toggle="tooltip" data-bs-offset="0,4" data-bs-placement="top" title="Delete Record">
    <button class="bg-label-danger cursor-pointer px-2 py-2 m-1 rounded-pill bx bx-trash border-0" data-bs-toggle="modal" data-bs-target="#deleteConfirmation{{$id}}"></button>
  </span>

    <div class="modal fade" id="deleteConfirmation{{$id}}" tabindex="-1" aria-hidden="true" data-bs-backdrop="static" data-bs-keyboard="false">
        <div class="modal-dialog modal-dialog-centered">
          <div class="modal-content">
            <div class="modal-header">
              <h5 class="modal-title" id="modalCenterTitle">Confirm Delete</h5>
              <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
            <div class="modal-body text-start">
              <h5 class="modal-title text-wrap" id="modalCenterTitle">Are you sure you want to delete {{$name}}?</h5>                      
            </div>
            <div class="modal-footer">
              <button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">
                Close
              </button>
              <button wire:click="delete({{$id}})" type="button" class="btn btn-danger">Yes</button>
            </div>
          </div>
        </div>
      </div>
</div>

this is my bulk_delete_button component

<div>
    <button class="bg-label-danger cursor-pointer px-2 py-2 m-1 rounded-pill bx bx-trash border-0" data-bs-toggle="modal" data-bs-target="#bulkDelete"></button>

    <div class="modal fade" id="bulkDelete" tabindex="-1" aria-hidden="true" data-bs-backdrop="static" data-bs-keyboard="false">
        <div class="modal-dialog modal-dialog-centered">
          <div class="modal-content">
            <div class="modal-header">
              <h5 class="modal-title" id="modalCenterTitle">Confirm Delete</h5>
              <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
            <div class="modal-body text-start">
              <h5 class="modal-title text-wrap" id="modalCenterTitle">Are you sure you want to delete {{$name}}?</h5>                      
            </div>
            <div class="modal-footer">
              <button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">
                Close
              </button>
              <button wire:click="bulkDelete" type="button" class="btn btn-danger">Yes</button>
            </div>
          </div>
        </div>
      </div>
</div>

If I don't use the blade component in the header everything works fine but when it is added none of it, if i change the dropdown at the footer from 10 records to something else it shows "Livewire encountered corrupt data"

luanfreitasdev commented 1 year ago

Do you also have the same problem with another component?

abhaypithadiya commented 1 year ago

If I have added the header blade then yes. If the bulk_delete is the only component, then everything works fine.

abhaypithadiya commented 1 year ago

Hey! Any update on this?

luanfreitasdev commented 1 year ago

I still haven't been able to reproduce the problem.

abhaypithadiya commented 1 year ago

Hello, you can reproduce the problem by adding blade components in action and headers array. Both the blade components are modals and have a function that is called when wire:click is used.

    public function actions(): array
    {
        return [
            Button::add('deleteButton')
                ->bladeComponent('delete_button', ['id' => 'id', 'name' => 'name']),
        ];
    }

    public function delete($id)
    {
        $result = BackOfficeUser::findOrFail($id)->delete();

        if ($result) {
            session()->flash('success', 'Back Office User Deleted Successfully!');
        } else {
            session()->flash('error', 'Database Error Occurred!');
        }

        return redirect(route('backOfficeUser.show'));
    }

    public function header(): array
    {
        return [
            Button::add('bulkDelete')
                ->bladeComponent('bulk_delete_button', ['name' => 'test']),
        ];
    }

    public function bulkDelete()
    {
        dd('test');
    }

this is the delete_button component

<div>
  <span data-bs-toggle="tooltip" data-bs-offset="0,4" data-bs-placement="top" title="Delete Record">
    <button class="bg-label-danger cursor-pointer px-2 py-2 m-1 rounded-pill bx bx-trash border-0" data-bs-toggle="modal" data-bs-target="#deleteConfirmation{{$id}}"></button>
  </span>

    <div class="modal fade" id="deleteConfirmation{{$id}}" tabindex="-1" aria-hidden="true" data-bs-backdrop="static" data-bs-keyboard="false">
        <div class="modal-dialog modal-dialog-centered">
          <div class="modal-content">
            <div class="modal-header">
              <h5 class="modal-title" id="modalCenterTitle">Confirm Delete</h5>
              <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
            <div class="modal-body text-start">
              <h5 class="modal-title text-wrap" id="modalCenterTitle">Are you sure you want to delete {{$name}}?</h5>                      
            </div>
            <div class="modal-footer">
              <button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">
                Close
              </button>
              <button wire:click="delete({{$id}})" type="button" class="btn btn-danger">Yes</button>
            </div>
          </div>
        </div>
      </div>
</div>

and this is the bulk_delete_component

<div>
    <button class="bg-label-danger cursor-pointer px-2 py-2 m-1 rounded-pill bx bx-trash border-0" data-bs-toggle="modal" data-bs-target="#bulkDelete"></button>

    <div class="modal fade" id="bulkDelete" tabindex="-1" aria-hidden="true" data-bs-backdrop="static" data-bs-keyboard="false">
        <div class="modal-dialog modal-dialog-centered">
          <div class="modal-content">
            <div class="modal-header">
              <h5 class="modal-title" id="modalCenterTitle">Confirm Delete</h5>
              <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
            <div class="modal-body text-start">
              <h5 class="modal-title text-wrap" id="modalCenterTitle">Are you sure you want to delete {{$name}}?</h5>                      
            </div>
            <div class="modal-footer">
              <button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">
                Close
              </button>
              <button wire:click="bulkDelete" type="button" class="btn btn-danger">Yes</button>
            </div>
          </div>
        </div>
      </div>
</div>

if the bladeComponent is present in the headers array, none of the the functions in the table works, not sorting or show per page.

abhaypithadiya commented 1 year ago

Hello! Any update on this issue?

luanfreitasdev commented 1 year ago

Hello @abhaypithadiya

I investigated this problem a lot and concluded that it is a wire:key problem. I added a wire:key on the button and it works.

wire:key="bulkDelete-{{ uniqid() }}"

<div>
    <button class="bg-label-danger cursor-pointer px-2 py-2 m-1 rounded-pill bx bx-trash border-0" data-bs-toggle="modal" data-bs-target="#bulkDelete"></button>

    <div class="modal fade" id="bulkDelete" tabindex="-1" aria-hidden="true" data-bs-backdrop="static" data-bs-keyboard="false">
        <div class="modal-dialog modal-dialog-centered">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title" id="modalCenterTitle">Confirm Delete</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                </div>
                <div class="modal-body text-start">
                    <h5 class="modal-title text-wrap" id="modalCenterTitle">Are you sure you want to delete {{$name}}?</h5>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">
                        Close
                    </button>
      // ------->>>>        <button wire:key="bulkDelete-{{ uniqid() }}" wire:click="bulkDelete" type="button" class="btn btn-danger">Yes</button>
                </div>
            </div>
        </div>
    </div>
</div>
abhaypithadiya commented 1 year ago

Hey @luanfreitasdev! Thanks for your reply. I added wire:key="bulkDelete-{{ uniqid() }}" but I still face the same error.

Livewire encountered corrupt data when trying to hydrate the [admin.back-office-user.back-office-user-listing-table] component. Ensure that the [name, id, data] of the Livewire component wasn't tampered with between requests.
abhaypithadiya commented 1 year ago

Hey @luanfreitasdev, Is there any other file I have to make changes in? Because the wire:key doesn't work for me.

luanfreitasdev commented 1 year ago

That is very strange. I tested it here and it worked

abhaypithadiya commented 1 year ago

Thanks for working on it. But unfortunately when I add wire:key it still shows the same error. None of it works when I add the bladeComponent in the header, in the button in the actions array it works perfectly.

CrazyBoy49z commented 1 year ago

In livewire, this happens when requests change during a request.

luanfreitasdev commented 1 year ago

I still don't know how to fix it besides wire:key

CrazyBoy49z commented 1 year ago

I still don't know how to fix it besides wire:key

I used nesting components once

abhaypithadiya commented 1 year ago

I still don't know how to fix it besides wire:key

I used nesting components once

Could you share an example please?

abhaypithadiya commented 1 year ago

I still don't know how to fix it besides wire:key

Hey! Thankyou so much for trying. Is it okay if I make a new repo and add you? So you can check if I am doing something wrong?

abhaypithadiya commented 1 year ago

In livewire, this happens when requests change during a request.

I tried using this https://stackoverflow.com/a/68836505 But It was the same request before and after hitting bulk_delete

CrazyBoy49z commented 1 year ago

I still don't know how to fix it besides wire:key

I used nesting components once

Could you share an example please?

https://laravel-livewire.com/docs/2.x/nesting-components

abhaypithadiya commented 1 year ago

Hey @CrazyBoy49z! I tried using nesting components, I am not sure if this is correct.

    public function header(): array
    {
        return [
            Button::add('bulkDelete')
                ->bladeComponent('bulk_delete_button', ['id' => '']),
        ];
    }

My bulk_delete_button component.

<div>
    @livewire('admin.test')
</div>

and my test livewire controller/blade

<?php

namespace App\Http\Livewire\admin;

use Livewire\Component;

class Test extends Component
{
    public function bulkDelete()
    {
        dd('test');
    }

    public function render()
    {
        return <<<'blade'
            <div>
            <div>
            <button class="bg-label-danger cursor-pointer px-2 py-2 m-1 rounded-pill bx bx-trash border-0" data-bs-toggle="modal" data-bs-target="#bulkDelete"></button>

            <div class="modal fade" id="bulkDelete" tabindex="-1" aria-hidden="true" data-bs-backdrop="static" data-bs-keyboard="false">
                <div class="modal-dialog modal-dialog-centered">
                  <div class="modal-content">
                    <div class="modal-header">
                      <h5 class="modal-title" id="modalCenterTitle">Confirm Delete</h5>
                      <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                    </div>
                    <div class="modal-body text-start">
                      <h5 class="modal-title text-wrap" id="modalCenterTitle">Are you sure you want to delete?</h5>                      
                    </div>
                    <div class="modal-footer">
                      <button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">
                        Close
                      </button>
                      <button wire:click="bulkDelete" type="button" class="btn btn-danger">Yes</button>
                    </div>
                  </div>
                </div>
              </div>
        </div>
            </div>
        blade;
    }
}

the bulk delete works but when I change the records per page it shows the data is corrupted again.

https://github.com/Power-Components/livewire-powergrid/assets/107384999/acb83d58-0966-424b-a8f5-166b52de5a79

CrazyBoy49z commented 1 year ago

If u use powergrid v3 Button bladeComponent work correctly with only id

I won't tell you about version 4 because I haven't used it. I immediately switch to 5

Detour

 ->addColumn('action', fn (Content $content) => view('admin.content.table-actions', [
           'model' => $content,
 ]));
Column::add()
         ->title('Actions')
         ->field('action')
         ->headerAttribute('', 'width: 50px;'),

Maibe Luan fixed it

abhaypithadiya commented 1 year ago

This issue happens only when I add bladeComponent in the header.

    public function header(): array
    {
        return [
            Button::add('bulkDelete')
                ->bladeComponent('bulk_delete_button', ['id' => '']),
        ];
    }

If I don't add this everything works perfectly.

CrazyBoy49z commented 1 year ago
$result = BackOfficeUser::findOrFail($id)->delete();

        if ($result) {
            session()->flash('success', 'Back Office User Deleted Successfully!');
        } else {
            session()->flash('error', 'Database Error Occurred!');
        }

        return redirect(route('backOfficeUser.show'));

try to replace with

BackOfficeUser::where('id', $id)->delete();

return redirect()->route('backOfficeUser.show');
CrazyBoy49z commented 1 year ago

Or use event https://v4.livewire-powergrid.com/table/component-settings.html#event-listeners

 public function getListeners()
    {
        return [
            "echo-private:controlsChannel,ControlEvent" => '$refresh',
        ];
    }
abhaypithadiya commented 1 year ago

Hey @luanfreitasdev ! I have added you to a repo. Please check it out. I still face the same error. Thankyou so much!

luanfreitasdev commented 1 year ago

Thanks for adding me, managed to identify and fix the problem!

abhaypithadiya commented 1 year ago

Thanks to you for fixing it!

Thanks for adding me, managed to identify and fix the problem!

luanfreitasdev commented 1 year ago

test again and let me know. thank you

abhaypithadiya commented 1 year ago

test again and let me know. thank you

Hey @luanfreitasdev ! Thank you so much for your help! Everything is work perfectly!