This is how you pass to a nested component
@livewire('user-profile', $user)
And if you are using includes in blade then you can be explicit in your Livewire component by saying
@include('user-profile', ['user' => $user])
Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.
I have an include that includes a list of tasks. I am converting that list of tasks to a Livewire component.
I have read how to pass variables to a component here: https://laravel-livewire.com/docs/mount-method/
But I can't get the data to be recognized as part of the include. Is it a bad idea to use a Livewire component as part of an include?
Includes always inherit the variables of the parent. It seems that Livewire components stand on their own as far as data is concerned.
Also, the functions of "render" and "mount" are confusing. In a Laravel controller, the 'return view' statement is in the same part of the controller where the data is handled.
Any words of wisdom? Thanks!
This is how you pass to a nested component
@livewire('user-profile', $user)
And if you are using includes in blade then you can be explicit in your Livewire component by saying
@include('user-profile', ['user' => $user])
Thanks for the tip, though I'm still having trouble.
My relationship trail looks like this: Contact->Deal->Task
And the relationships are set up properly and the queries work fine everywhere. I am simply trying to add Livewire functionality.
My main view for a Contact has an include for deals.index:
@include('deals.index')
This file has a div that calls the new livewire view through its controller:
<div>
@livewire('tasks', $deals)
</div>
I added the variable $deals here which are associated with the tasks I want in my unordered list in my 'Tasks' Livewire component.
My livewire controller file looks like this:
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use Illuminate\Http\Request;
use App\User;
use App\Contact;
use App\Deal;
use App\Task;
class Tasks extends Component
{
public function render()
{
return view('livewire.tasks');
}
}
My Livewire component view looks like this:
<div>
Livewire Tasks
<ul class="list-group">
@foreach($deal->tasks as $task)
<li class="list-group-item">
<input type="checkbox" class="mr-4">
<p>{{Carbon\Carbon::parse($task->taskduedate)->format('m/d/Y')}} - {{$task->tasktext}}</p>
</li>
@endforeach
</ul>
<ul class="list-group">
<li class="list-group-item d-flex justify-content-between align-items-center">
<div>
<input type="checkbox" class="mr-4">
Finish livewire screencast
</div>
</li>
<li class="list-group-item d-flex justify-content-between align-items-center">
<div>
Mow the lawn
</div>
</li>
<li class="list-group-item d-flex justify-content-between align-items-center">
<div>
Buy toilet paper
</div>
</li>
</ul>
</div>
My view has a dynamic list followed by a static list I was using for testing.
The error I get is: Undefined variable: deal on this line:
@foreach($deal->tasks as $task)
I know that the $deals variable is being passed, but it seems that the relationship between Deals and Tasks is not picked up in a Livewire component the same way it is in a Blade view.
Should I put everything into a Livewire component with its controller and view, or is there something I am not passing correctly? Thanks!
But you are passing $deals to the Livewire component and not singular $deal as shown
<div>
@livewire('tasks', $deals)
</div>
So you need to wrap it within another foreach
@foreach($deals as $deal)
@foreach($deal->tasks as $task)
// do stuff
@endforeach
@endforeach
Yes. Isn't that why @foreach statements have ($deals as $deal) in them before using $deal->tasks? Again, this works in a regular view just fine. It pulls up the data. No variable errors. Only with Livewire.
I do not see that you have two foreach loops in what you've shown above? What am I missing?
Anyway Livewire components are designed for reactivity, how is this component reactive? You are not fetching the data from it nor you are doing any manipulation?
Sorry. Let me clarify. I did this in the main view that includes the Livewire tasks view. It has the first @foreach loop:
@foreach($deals as $deal)
Have you tried two foreach loops?
Then you are wrong again, you have to change
@livewire('tasks', $deals)
// to
@livewire('tasks', $deal)
Ok. Made the change to:
@livewire('tasks', $deal)
Still get the Undefined variable: deal error on this line:
@foreach($deal->tasks as $task)
Do I need to add anything to the Livewire controller?
Try this
@livewire('tasks', $deal, key($deal->id))
Should I put everything into a Livewire component with its controller and view, or is there something I am not passing correctly? Thanks!
Probably yes. That is how it was designed to work.
Same error. So weird.
Just move everything to Livewire component and it will work. It has to work.
I was thinking about doing that. Could it be that I need to do something with the mount() method to get the data passed over, besides the render() method for the view?
The mount() method example at https://laravel-livewire.com/docs/mount-method/ seems strange to me, but maybe it makes sense to you.
In their example, the variable sent is 'contactId', but the variable received by the mount function is 'id'. Then they run a query to define 'Contact', the defines the fields individually.
Doesn't seem like a practical Laravel style example.
By the looks of it, it seems that you have to pass following:
@livewire('tasks', $deal->id)
public $deal;
public function mount($dealId)
{
$this->deal = Deal::find($dealId);
}
Good idea.
Though now I get this error:
Livewire component's [tasks] public property [deal] must be of type: [numeric, string, array, null, or boolean]. Only protected or private properties can be set as other types because JavaScript doesn't need to access them.
Because 'deal' is a collection, which I have been taught by Laravel to use Relationships along with Collections for all of my data. But now the Laravel Javascript PHP miracle can't use Collections?
What is my life?
https://github.com/livewire/livewire/issues/488
Yap, security measure.
Just move everything to LW and you'll be just fine.
I can't even dd($deal) at the top of the Livewire component controller in the mount() method or the render() method to make sure it is receiving the variable '$deal'. When I try it tells me gives me the 'Undefined variable' error again. So, either the variable is undefined, or it's a collection, which Livewire can't use.
Huh?
I like that idea. But by "move everything", do you mean my whole app, or just the contact view, which includes the deal view, which includes the tasks Livewire component?
I like that idea. But by "move everything", do you mean my whole app, or just the contact view, which includes the deal view, which includes the tasks Livewire component?
Everything from the top level foreach loop.
@livewire('deals')
Got it. I'll give that a try. I'll let you know how it goes. :)
It is pretty easy. I'm sure it will go well.
Ok, so now I can get the $deals to dd() properly from the Deals.php Livewire controller, and it includes the underlying tasks collection, so the data is getting to the controller, but I can't get it into the Livewire view.
I get the "Undefined variable: deals" error.
Here is my updated code:
Line calling the Livewire component:
@livewire('deals', $deals)
Livewire Controller:
<?php
namespace App\Http\Livewire;
use Livewire\Component;
class Deals extends Component
{
public $deals;
public function mount($deals)
{
return view('livewire.tasks', [
'deals' => $deals
]);
}
}
Livewire View:
@foreach($deals as $deal)
<div class="col-md-6">
<div class="well">
<div class="row">
<div class="col-md-9"><h3><a href="/deals/{{$deal->id}}">{{$deal->dealtype}}</a></h3></div>
<div class="col-md-3">
<button type="button" class="btn btn-primary btn-sm" data-toggle="modal" data-contactid="{{$contact->id}}" data-dealid="{{$deal->id}}" data-dealtype="{{$deal->dealtype}}" data-price="{{$deal->price}}" data-commissionpercentage="{{$deal->commissionpercentage}}" data-target="#editDealModal">Edit</button>
<a href="link_to_action('DealsController@destroy', $title, $parameters = array(), $attributes = array());">Delete</a>
</div>
</div>
<div class="row">
<div class="col-md-6"><h4>Price: {{moneyformat($deal->price)}}</h4></div>
<!-- Calculation for Commission dollars from Price and CommissionPercentage -->
<div class="col-md-6"><h5> Comm: {{moneyformat($deal->price * $deal->commissionpercentage * .01)}} - ({{$deal->commissionpercentage}}%)</h5></div>
</div>
<div class="tasks">
<h5>Tasks</h5>
<div class="card-block">
{!! Form::open(['route' => ['tasks.store']]) !!}
{{ csrf_field() }}
<div class="form-group">
{{Form::textarea('tasktext', null, array('placeholder' => 'Your task here', 'class' => 'form-control', 'rows' => '2'))}}
</div>
<div class="form-group">
{{Form::text('taskduedate', null, array('placeholder' => 'Due Date', 'class' => 'form-control', 'data-provide' => 'datepicker', 'data-date-autoclose' => 'true', 'data-date-today-highlight' => 'true'))}}
</div>
<div class="form-group">
{{Form::submit('Add Task', array('class' => 'btn btn-primary'))}}
</div>
<input type="hidden" name="deal_id" value="{{ $deal->id }}">
{{Form::close()}}
</div>
<div>
Livewire Tasks
<ul class="list-group">
@foreach($deal->tasks as $task)
<li class="list-group-item">
<input type="checkbox" class="mr-4">
<p>{{Carbon\Carbon::parse($task->taskduedate)->format('m/d/Y')}} - {{$task->tasktext}}</p>
</li>
@endforeach
</ul>
<ul class="list-group">
<li class="list-group-item d-flex justify-content-between align-items-center">
<div>
<input type="checkbox" class="mr-4">
Finish livewire screencast
</div>
</li>
<li class="list-group-item d-flex justify-content-between align-items-center">
<div>
Mow the lawn
</div>
</li>
<li class="list-group-item d-flex justify-content-between align-items-center">
<div>
Buy toilet paper
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
@endforeach
So, again, if I add:
dd($deals);
to the Livewire Deals Controller, it dumps a collection of 2 arrays. A deal in each array, with that tasks showing as an array under "relations", as their own collection, as I believe it is supposed to, exactly as it should be in the DB.
However, this data is not getting to the view.
i see where your problem is, you were doing this:
return view('livewire.tasks', [
'deals' => $deals
]);
when you should of been doing this:
return view('livewire.tasks', [
'deals' => $this->deals
]);
Why don't you retrieve them from Livewire Component itself and not to pass it?
I don't know what that means. How do I do that?
Unless you mean, why don't I run the queries within the Livewire component to lookup the values I want?
Because I already have ran the queries, in the previous view that calls the Livewire component.
And it defeats the DRY principle of development. The $deals collection is sitting in the Livewire controller. It should be easily passed to the view, but I have tried every syntax I can think of. Livewire is made for Laravel. It should work with collections and arrays easily.
How do I get that data of the $deals collection into the view?
I haven't had any issues when I tried it. Don't see your point on moving the query to Livewire component since you will remove it from Laravel's controller.
@wallyj how do you solved you problem?
I had the same situation, I solved the problem after 8 hours. The problem is because you got a collection so you only need to convert your collection to array and done. All of this in Mount function.
Please or to participate in this conversation.