Search code examples
phplaravellaravel-livewirelaravel-10

Livewire property not showing when refreshing


I'm doing a simple comment section for posts in a Laravel Livewire application and it should be able to live update when a new comment is made. However, when I comment something in a post, I got the Following error:

Undefined array key "class". With the error being thrown at: public/index.php

$response = $kernel->handle(
    //Right here
    $request = Request::capture()

)->send();

In the laravel.log I got the following markup:

Undefined array key "class" {"userId":1,"exception":"[object] (ErrorException(code: 0): Undefined array key \"class\" at vendor\\livewire\\livewire\\src\\HydrationMiddleware\\HydratePublicProperties.php:155)

In my code, I have a Timeline livewire component, which calls a foreach loop for posts.

//timeline component
@foreach ($this->posts as $post)
    <livewire:post :post="$post" wire:key="post-{{$post->id}}" />
@endforeach

That calls another loop for comments.

//post component
@foreach($this->comments as $comment)
    <livewire:comment.view :comment="$comment" wire:key="comment-{{$comment->id}}" />
@endforeach

And it looks like this inside the comment.view component:

//comment component
<div class="flex flex-col items-center gap-1">
    <p class="font-semibold">{{$comment->user->name}}</p>
    <p class="grow font-medium">{{$comment->body}}</p>
</div>

Controllers:

Comment.view

class View extends Component
{
    public Comment $comment;

    public function mount(Comment $comment = null) {
        $this->comment = $comment;
    }

    public function render()
    {
        return view('livewire.comment.view');
    }
}

Post.view

class Post extends Component
{
    public Item $post;

    protected $listeners = [
        'comment::created' => '$refresh'
    ];

    public function mount(Item $post = null) {
        $this->$post = $post;
    }

    public function render()
    {
        return view('livewire.post');
    }

    public function getCommentsProperty() {
        $comments = $this->post->comments;

        return $comments;
    }
}

The comments are being shown when I first open the browser, I only got this error after trying to create a new comment, which is actually being created and shows off when I F5 the browser after the error log.

Have already tried placing the all comments in the timeline component and refreshed it, making it work nicely. It only happens when I use it inside post.view component.


Solution

  • Got by this changing the place where i setted the attributte. The mount() function only runs once, and whenever I send an event for it to refresh, it won't run. Instead, I should define the comments attribute that the comment.view receives in the render() method. Just like this

    Before:

    public function mount(Comment $comment = null)
    {
        $this->$comment = $comment;
    }
    

    After:

    public function render(Comment $comment)
    {
        $this->$comment = $comment;
    
        return view('livewire.comment.view');
    }
    

    Also, I've done a misstype writing $this->comment instead of $this->$comment