Error in Action: "$ownerRecord must not be accessed before initialization"

Hello, I'm trying to access livewire->ownerRecord inside an action but i'm getting the error in the title. Here is my code
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('id')->sortable(),
Tables\Columns\TextColumn::make('seller.organization')->sortable(),
Tables\Columns\TextColumn::make('lead_time_value')->sortable(),
Tables\Columns\TextColumn::make('lead_time_unit')->sortable(),
Tables\Columns\TextColumn::make('quote')->sortable(),

])
->filters([
//
])
->headerActions([])
->actions([
Action::make('assign')
->label('Assign')
->action(function (Quote $quote, RelationManager $livewire) use ($table) {
dd($livewire->ownerRecord);
OrderItem::find(self::$order_item_id)->assign($quote);
})
])
->bulkActions([]);
}
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('id')->sortable(),
Tables\Columns\TextColumn::make('seller.organization')->sortable(),
Tables\Columns\TextColumn::make('lead_time_value')->sortable(),
Tables\Columns\TextColumn::make('lead_time_unit')->sortable(),
Tables\Columns\TextColumn::make('quote')->sortable(),

])
->filters([
//
])
->headerActions([])
->actions([
Action::make('assign')
->label('Assign')
->action(function (Quote $quote, RelationManager $livewire) use ($table) {
dd($livewire->ownerRecord);
OrderItem::find(self::$order_item_id)->assign($quote);
})
])
->bulkActions([]);
}
20 Replies
guitarnerd_
guitarnerd_OP15mo ago
it worked all of a sudden but $quote->id (or any attribute) is now null
toeknee
toeknee15mo ago
dd($quote) I suspect the relationship quote is broken
guitarnerd_
guitarnerd_OP15mo ago
@toeknee dd($quote) gives me the model class
No description
guitarnerd_
guitarnerd_OP15mo ago
In case it's relevant the action is inside a relation manager I'm wondering if the reason could be related to the fact that the relation is a HasManyThrough
cheesegrits
cheesegrits15mo ago
Try using $record instead of $quote as the param name in your action() closure. Parameter injection is done by name, so Filament knows what $record is, it doesn't know what $quote is. So when the docs give examples of callback closures with injected param names, you typically have to use those exact names.
guitarnerd_
guitarnerd_OP15mo ago
@Hugh Messenger Thanks a lot. it worked. I had no idea that was necessary.
cheesegrits
cheesegrits15mo ago
When you think about it, it makes sense. Filament doesn't know anything about your app or usage, it has no idea what a $quote is, or how to inject it into the closure.
guitarnerd_
guitarnerd_OP15mo ago
I thought it would know that using the positioning of the arguments
cheesegrits
cheesegrits15mo ago
Again, when you think about it, there is no argument positioning, as closures are anonymous functions with no signature. This is one of those slightly tricky things in Filament, which there isn't really any IDE magic or language features that can help. To figure out what param are available in any given callback closure, you pretty much have to dig thru the docs. Although you get used to it after a while, and pretty much get to know what's going to be available where.
guitarnerd_
guitarnerd_OP15mo ago
Yeah I think I need to read a bit more about closure to fully grasp it
cheesegrits
cheesegrits15mo ago
There's nothing really magic about closures, they are just little anonymous, inline functions that can get called. The magic part is how the paramater injection works, which is always going to depend on the context. If it's a closure on a form field, then there is most likely a $state, $get / $set, etc. In a table row action there will be a $record. Etc.
guitarnerd_
guitarnerd_OP15mo ago
and you can insert those in any order you want right ? and each of them is optional?
cheesegrits
cheesegrits15mo ago
Correct. Filament just looks at all the parameter names (and types) you specified in your closure, and attempts to match then against whatever data it has in the context of the callback. In your first attempt, notice that you got a model class for $quote. That's where Filament went "OK, I don't know what $quote is, but the Quote type is a model class, so I'll give him an instance of that". When you changed the name to $record, Filament knows you want the table row record, because the context is a table row action, and $record is one of the predefined param names it expects in that context.
guitarnerd_
guitarnerd_OP15mo ago
That's pretty neat! Thanks for the explanation.
cheesegrits
cheesegrits15mo ago
N/p
guitarnerd_
guitarnerd_OP15mo ago
@Hugh Messenger one last question. Any idea where I can find all the possible parameters I can pass to the closure ?
charleswilfriedk
charleswilfriedk15mo ago
I have a follow up question here https://discord.com/channels/883083792112300104/1152920132897755236 How do i use ownerRecord and record inside a successNotification for that action
cheesegrits
cheesegrits15mo ago
There isn't really a single place in the docs, because it's so dependent on where your closure is. So you just have to dig in to the docs for whatever it is you are using a closure on. Each section of the docs (tables, forms, actions, etc) have a generic "Utility Injection" section (search for "inject"), but they don't always list everything. You have to read the code exaqmples ffor whatever it is you are doing.
guitarnerd_
guitarnerd_OP15mo ago
Noted! Thanks @Hugh Messenger
cheesegrits
cheesegrits15mo ago
I'll respond on that thread.
Want results from more Discord servers?
Add your server