trondhuso's avatar

Unable to call component method. Public method [toJSON] not found on component

In my web application I have a few dropdowns where a user can click on different checkboxes. When that happens, the result table is being re-rendered.

Seconds later I get the modal telling me: Unable to call component method. Public method [toJSON] not found on component

And then I see this in the body in the laravel debug-modal. I upgraded from LW2 to LW3, so that could be a reason, but I am not sure. There are no emits, just dispatches

response:

1 like
5 replies
LaryAI's avatar
Level 58

Certainly! This error is common when upgrading from Livewire v2 to v3, and it’s related to how Alpine.js and Livewire interact, especially with $wire references in your JavaScript or Alpine code.

Why does this happen?

In Livewire v3, the $wire object no longer exposes all public methods and properties directly. Instead, it provides a proxy for calling Livewire component methods. However, if you try to use $wire.toJSON() (or something similar), it will attempt to call a toJSON method on your Livewire component, which does not exist by default—hence the error:

Unable to call component method. Public method [toJSON] not found on component

Common Cause

You likely have some Alpine.js code (or a third-party Alpine plugin) that tries to serialize $wire by calling .toJSON() on it, which worked in v2 but not in v3.

For example:

console.log($wire.toJSON());

or

JSON.stringify($wire)

or even

Alpine.store('someStore', $wire)

Some libraries or custom code may attempt to serialize $wire for debugging or state management.


Solution

1. Remove or Refactor Calls to $wire.toJSON() or JSON.stringify($wire)

You should not attempt to serialize the $wire object. If you need data from your Livewire component, access the public properties directly:

console.log($wire.someProperty);

If you need to get all data, consider creating a public method on your Livewire component that returns the data you need:

// In your Livewire component
public function getData()
{
    return [
        'municipality' => $this->municipality,
        // ...other properties
    ];
}

Then call it from Alpine/JS:

$wire.getData().then(data => {
    console.log(data);
});

2. Check for Third-Party Alpine Plugins

Some Alpine plugins (like Alpine Persist or custom stores) may try to serialize $wire. If you’re using such plugins, make sure you’re not passing $wire directly into them.


3. Search Your Codebase

Search for toJSON or JSON.stringify($wire) in your JS/Blade files and refactor/remove those usages.


4. If You Need to Sync State

If you need to sync state between Alpine and Livewire, only sync the specific properties you need, not the whole $wire object.

Example:

Alpine.data('myComponent', () => ({
    municipality: $wire.municipality,
    // ...
}));

Summary

  • Do not call $wire.toJSON() or JSON.stringify($wire).
  • If you need data, expose it via a public method or access properties directly.
  • Check for Alpine plugins or custom code that might be serializing $wire.
  • Refactor your code to only use the data you need.

If you provide a code snippet or more context where $wire.toJSON() is being called, I can give a more targeted fix! But the above should resolve the error you’re seeing after upgrading to Livewire v3.

trondhuso's avatar

some more "debugging": It also happens after clicking on paginator - going from one page to another. so it is related to rendering new items.

            
           POST http://internalsite.local/livewire/update 500 (Internal Server Error)
trondhuso's avatar

Latest update.

After trying different things I deleted the node_modules directory and installed the nodes packages again. It solved the problem - as far as I can see

2 likes
adevade's avatar

This fixed it for me as well! 👍 I had the same error after upgrading from Filament v3 to v4.

Please or to participate in this conversation.