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

yehuuu6's avatar

Can't pass resource to the Livewire 3 component.

When I try to pass a resource to the livewire component;

class ShowPost extends Component
{
    public $resource;

    public function mount(Post $post)
    {
        $post->load('user');

        $this->resource = PostResource::make($post);
    }

    public function render()
    {
        return view('livewire.pages.posts.show-post', [
            'post' => $this->resource,
        ]);
    }
}

I get the error: Property type not supported in Livewire for property

So Livewire 3 does not accept resources as properties. (We are trying to assign PostResource to the public $resource variable.). I solved this by converting the object into an array using resolve() function.

class ShowPost extends Component
{
    public $resource;

    public function mount(Post $post)
    {
        $post->load('user');

        $this->resource = PostResource::make($post)->resolve();
        $this->resource['user'] = $this->resource['user']->resolve();
    }

    public function render()
    {
        return view('livewire.pages.posts.show-post', [
            'post' => $this->resource,
        ]);
    }
}

I also had to convert the loaded user object because it was causing the same problem. Anyways, I can use the array in the view perfectly by going $post['user']['username'] or I can convert it into an object again with

@php
    // Convert the post array to an object
    $post = json_decode(json_encode($post));
@endphp

// Use the object in the blade view.
<h1>{{ $post->user }}</h1>

But I wonder, why is this a problem? Am I doing something wrong?

0 likes
8 replies
LaryAI's avatar
Level 58

The issue you're encountering is due to the fact that Livewire properties must be serializable. Livewire uses JavaScript to communicate with the backend, and it needs to be able to serialize and deserialize the data being passed back and forth. Eloquent models and resources are not inherently serializable, which is why you're running into this problem.

Your solution to convert the resource to an array using the resolve() method is a good approach. This ensures that the data is in a format that Livewire can handle. However, you can simplify your code a bit and avoid the need to manually convert nested objects.

Here's a refined version of your solution:

use Livewire\Component;
use App\Models\Post;
use App\Http\Resources\PostResource;

class ShowPost extends Component
{
    public $resource;

    public function mount(Post $post)
    {
        $post->load('user');
        $this->resource = PostResource::make($post)->resolve();
    }

    public function render()
    {
        return view('livewire.pages.posts.show-post', [
            'post' => $this->resource,
        ]);
    }
}

In your Blade view, you can directly access the array data without needing to convert it back to an object:

<!-- livewire/pages/posts/show-post.blade.php -->
<h1>{{ $post['user']['username'] }}</h1>

Explanation

  1. Serialization Requirement: Livewire properties must be serializable. Eloquent models and resources are not serializable by default, which is why you encountered the error.

  2. Using resolve(): The resolve() method converts the resource into an array, making it serializable and suitable for Livewire properties.

  3. Avoiding Nested Object Conversion: By ensuring that the entire resource is converted to an array, you avoid the need to manually convert nested objects.

Why This Happens

Livewire needs to serialize the data to JSON to send it to the frontend. Eloquent models and resources contain complex relationships and methods that cannot be easily serialized. By converting the resource to an array, you strip it down to its basic data, which can be serialized and deserialized without issues.

Best Practices

  • Keep Data Simple: When working with Livewire, always ensure that the data you pass to the frontend is simple and serializable.
  • Use Resources Wisely: Resources are great for transforming data, but remember to convert them to arrays when passing them to Livewire components.

By following these practices, you can avoid serialization issues and ensure smooth communication between your Livewire components and the backend.

tykus's avatar

What are you actually doing here @yehuuu6 The Component that makes sense; why do you set a public property and pass that same data in the render function? You seem to be missing the point of Eloquent API Resources

Anyway, the error message means the type is not supported just like it describes in the docs.

yehuuu6's avatar

@tykus I am trying to hide the email response. The UserResource only returns the email if the users is authenticated. I was following the tutorial and I tried to use the same thing on my app. It is working fine now. The email is not visible if the user is not the author of the post.

Was just curious, why livewire makes it hard to use resources.

tykus's avatar

@yehuuu6 what???

I am trying to hide the email response. The UserResource only returns the email if the users is authenticated.

the tutorial

What tutorial?

why livewire makes it hard to use resources

Livewire !== API

yehuuu6's avatar

@tykus Thanks for responding quickly. This is the tutorial

Luke Downing uses Vue and Inertia, I was following along with livewire. They are creating API resources for user, post and comment models. So I did the same. Was confused when I couldn't pass the resource directly to the blade template using livewire components. I am also a learner at this point. So why do you reply to me like I am experienced and doing some weird mistakes on purpose?

tykus's avatar
tykus
Best Answer
Level 104

@yehuuu6 there is a reason that the tutorial is using API Resources - Vue is a JavaScript framework that understands and uses JSON in client-rendered templates. On the other hand, Livewire and Blade embraces the backend. Livewire returns server-rendered HTML - you control what that HTML looks like in your Blade template, e.g. if you want to show an email address only is the current user is authenticated (or whatever the example was):

@auth
{{ $user->email }}
@endauth

If you need to keep data secret, don't put it in public properties on the Component class. And whenever you do set public properties on the Component class, make sure they adhere to the supported property types

1 like
yehuuu6's avatar

@tykus Thanks for the clarification mate. It all makes sense now.

Snapey's avatar

Think of Livewire more like a blade template. Pass the data you need to display in the render method, and only use public properties for things that the client needs to change.

See Philo Hermans talk at Laracon 2024 today. Its on youtube, search for laravelphp

1 like

Please or to participate in this conversation.