I have a form in a Blade template that utilises Livewire:
{{-- resources/views/page-generation.blade.php --}}
<div class="py-12">
<livewire:titlegen.form />
</div>
The form looks like this
<?php
// app/Livewire/Titlegen/Form.php
namespace App\Livewire\Titlegen;
use Livewire\Component;
class Form extends Component
{
// Two way (entered by user, but need to be reflected on screen when loading)
public string $productName;
public string $targetAudience;
public string $usps;
public string $cta;
public string $keyPhrases;
// Outputs (generated on server, shown to user)
public ?array $titles;
public ?string $ctaOut;
public ?string $error;
// Outputs (stored on server, shown to user)
public array $menus = [
// Long menu to render
];
public function boot(ExampleDependency $dependency): void
{
// Set dependencies...
}
// Some Livewire action methods here...
}
The first two categories do require binding. The first group are two way, and although the second group are only one way, they are small, and it is not a great bother they are send in the wrong direction.
But the $menus
is an interesting one. I want to set it in the Component class, and it is already exposed in the template as I want, but this means that it becomes treated as a bound property, so it will be send from the client back to the server. (I don't want this to happen, as it is a waste of bandwidth, but moreover it unnecessarily complicates my server input filtering).
I suppose I can just set this in the template, but that feels a bit hacky. Is there a dynamic way I can pass PHP variables to the rendered template without them becoming bound in the two way process?
I've been reading about Wireables, and I suppose I could use that to collapse private data into a harmless null value. But that feels rather like a laborious hack, rather than a solution. Is there anything better?
Ah, having posted a question on this, I was inspired to try something, and I have a solution. The problem I had was that I did not have a render()
method in my Component class, since by default it does not need one. Laravel uses some magic to derive a default Blade template from the name and folder of the class.
In reality it is doing this under the hood:
public function render(): View
{
return view('livewire.titlegen.form');
}
I think this Component was generated by an artisan
function, and so I just used it as it came.
With the above discovery made, I could pass a variable to the template:
public function render(): View
{
return view(
'livewire.titlegen.form',
['menus' => $this->menus, ]
);
}
And then finally in the class properties, change it from public
, which hides it from the two-way binding mechanism:
protected array $menus = [
// Long menu to render
];