daveb2's avatar

Livewire V3 how to update blade component

Something that was possible with Livewire V2 was updating a property of a model instance attached to a parent blade file (ie. non-livewire component) from a nested Livewire component.

In other words you could have a livewire component called EditPost, and have it included in your blade file like so:

#Livewire V2

PostController.php file

class PostController extends Controller
{
	public function edit(Post $post)
	{
		return view('edit-post', [
			'post' => $post,
		]);
	}
}

edit-post blade file

...
<livewire:edit-post-name :post="$post" />
...

EditPostName.php

class EditPost extends Component
{
	public Post $post;

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

	public function render()
	{
		return view('edit-post-name');
	}

	public function updateName()
	{
		$this->post->name = 'updated name';
	}
}

edit-post-name.blade.php

<x-form.button wire:click="updateName()">Update</x-form.button>

<input type="text" wire:model.live="post.name"/>

When we run the above and pass in an existing post object, and click the Update button, we see the contents of the input change to read Update as expected.

However, when we submit the form on the view edit-post.blade.php (the parent), the updated ->name attribute is not passed in to the update route on the controller.

More specifically, it is passed back, but the value is always null:

public function updateRequest $request, Post $post)
{
	dd('name', request()->name);
}

output

"name" // app/Http/Controllers/PostController.php:114
null // app/Http/Controllers/PostController.php:114

However, downgrading Livewire to V2 fixes this behaviour and the updated name field is passed back correctly to the update route.

Does anyone have any ideas on how to make this work in Livewire V3, or is this behaviour no longer supported in V3? The documentation seems to suggest this is still supported (https://livewire.laravel.com/docs/components#rendering-components) but perhaps I have misread it.

If anyone has any better alternatives for how to update the model instance in the blade view from an included livewire component that would be great too.

0 likes
3 replies
daveb2's avatar

@vincent15000 thanks for the reply. I tried adding the #[Modelable] attribute against the model instance but I couldn't get that to work. Reading the docs on the new #[Modelable] attribute leads me to believe that you can only use it on a single property I think?

Currently Livewire only supports a single #[Modelable] attribute, so only the first one will be bound.

I don't think that would be greatly useful anyway. I guess that the old way of including livewire components inside blade and passing in the model instance from the route is not a thing anymore and I'll have to use a complete livewire view instead if I want to use a livewire component. For now I have just hacked my way around this file upload problem with a mixture of alpine.js and regular js, but it would have been easier and more maintainable if I could have used Livewire.

1 like
vincent15000's avatar

@daveb2 Have you tried this ?

dd('name', $request->name);

It should give you exactly the same result, but perhaps it's worth trying.

Please or to participate in this conversation.