Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

RileyGWeb's avatar

"Livewire encountered corrupt data when trying to hydrate component"

This is a very bizarre and complex one, so stay with me.

I am using Livewire Datatables ( https://github.com/MedicOneSystems/livewire-datatables ) to build a custom filtering feature for my analytics dashboard app. This feature presents the user with a list of metrics which they can select, and this selection is passed through the application to build a query that hits the database and returns data to the user, in the form of an HTML table.

Originally I was using it to build a regular HTML table, and all was well. However I am in need of greater filtering abilities on the table itself, which is where Livewire Datatables comes in. If you are unfamiliar with Livewire Datatables, below is a sample of how the columns are structured in a Livewire Datatable component.

<?php

namespace App\Http\Livewire\Traffic;

use App\Models\Traffic;
use Mediconesystems\LivewireDatatables\Column;
use Mediconesystems\LivewireDatatables\DateColumn;
use Mediconesystems\LivewireDatatables\Http\Livewire\LivewireDatatable;
use Mediconesystems\LivewireDatatables\NumberColumn;

class Trafficpivottable extends LivewireDatatable
{
    public $model = Display::class;

    public function builder()
    {
    // join to relational tables if necessary
        return Traffic::query()
            ->leftJoin('sites', 'sites.id', 'traffic.sites_id')
            ->leftJoin('devices', 'devices.id', 'traffic.devices_id');
    }

    public function columns()
    {
        return [ // Columns are built here - these will directly correspond to what is queried in the database as well as what is built on the front-end table
            DateColumn::name('date')
                ->label('Date')
                ->filterable()
                ->hideable(),
            Column::name('sites.name')
                ->label('Site')
                ->filterable()
                ->hideable()
                ->hide(),
            Column::name('devices.name')
                ->label('Device')
                ->filterable()
                ->hideable(),
            NumberColumn::name('sessions')
                ->label('Sessions')
                ->filterable()
                ->hideable(),
        ];
    }
}

This goes to the SQL database, grabs those 4 columns and outputs a dynamic HTML table with 4 columns. Pretty straightforward. When hardcoded like this, it works just fine.

My problem is that I need to dynamically build these columns as per the user's input. Below is an illustration of the structure I have so far:

There are two Livewire components here - the Custom Filter which has the vanilla filtering UI that I built, and the Custom Report component which is a Livewire Datatable. Livewire Datatables do not have blade views.

It starts in the Custom Filter Livewire component. The user makes a selection, Javascript in the blade view gathers their selection and passes it to the controller.

// custom-filter.blade.php
Livewire.emit('submitReport', submittedList);

The controller then uses that data to create an array that can be used by the datatable Livewire component to build the columns seen above. At the end, a Livewire emit is called to the datatables component which it passes the column data to.

// CustomFilter.php
public function submitReport($submittedList)
    {
        $cols = [
            [
                'column' => 'Mediconesystems\\LivewireDatatables\\DateColumn', // This is called an FQNS - fully qualified namespace. It is necessary for the next step; simply including 'DateColumn' here produces a "no such class exists" error
                'name' => 'date',
                'label' => 'Date',
                'filterable' => true,
                'hideable' => true,
            ],
            [
                'column' => 'Mediconesystems\\LivewireDatatables\\Column',
                'name' => 'sites.name',
                'label' => 'Site',
                'filterable' => true,
                'hideable' => true,
            ],
            [
                'column' => 'Mediconesystems\\LivewireDatatables\\Column',
                'name' => 'devices.name',
                'label' => 'Devices',
                'filterable' => true,
                'hideable' => true,
            ],
        ];

        $this->emit('displayReport', $cols);
    }

The Livewire Datatable component is given the column data and asked to execute.

// Customreport.php
public function displayReport($cols) 
    {  
        foreach($cols as $key => $val) {
            $instance = app()->make($val['column']);
            $columnName = $val['name'];
            $item = $instance->name($columnName);
            $item->filterable = true;
            $item->hideable = true;

            array_push($this->cols, $item);
        }

        $this->ready = true;
    }

    public function columns()
    {
        if ($this->ready) {
            return $this->cols; // This is where the query happens. My assumption is that the Livewire component will refresh and $this->ready will be set to true, before this method is called again.
        } else {
            return [];
        }
    }

A dd($this->cols) returns exactly what is needed to build the columns, identical to if there was no passing around through components. In other words, it builds the column objects properly.

When I hit the submit button to send it through that chain, the error appears. The full error states: Livewire encountered corrupt data when trying to hydrate the [customreport] component. Ensure that the [name, id, data] of the Livewire component wasn't tampered with between requests.

I looked in the Laravel debugbar and none of those three items seem to change, although all other livewire components dissapear from the debugbar when I click submit. For whatever reason.

I also attempted to move everything to the columns() method and pass the $cols property in there, but that's not allowed. Not compatible with Livewire Datatables I guess.

Can anyone help?! Thank you so much in advance if you even read this far. I spent a good 45 minutes formatting this question, which is a fraction of the the time I've spent banging my head on the wall about this error.

0 likes
5 replies
shawnveltman's avatar

Did you try putting the javascript into a div with a "wire:ignore" around it?

shawnveltman's avatar

@Coaster132 Curious if you ended up solving this. If so, please post an update to help future searchers with the same issue! :)

RileyGWeb's avatar

@shawnveltman Unfortunately, I did not. I am just hardcoding a solution for now, and honestly I'm unsure what I'm going to do in the future. If I ever find anything though, I will certainly come back and update.

shawnveltman's avatar

You've probably already done this, then, but the only thing I can suggest is ripping out as much code as you can to see if you can isolate where the error occurs.

EG:

  • What happens when you pass the listener an empty string, and have your JS just console log the contents? If that causes the error, then you know it's not an issue with the data you're passing to the component. If it does, then you can work on trimming down the data being passed

  • If it's not the data, then create a throwaway component who's only job is to accept that data... Then slowly start adding to it the main component functionality until you can identify what caused the error.

Please or to participate in this conversation.