When i make a form component reactive, it crashes

DateTimePicker::make('publish_date')->required()->default(now())->reactive()->afterStateUpdated(function (\Closure $set, $state) {
$newPublishDate = \Illuminate\Support\Carbon::createfromFormat("Y-m-d H:i:s", $state);

$this->isPublished = $newPublishDate < now();
}),
DateTimePicker::make('publish_date')->required()->default(now())->reactive()->afterStateUpdated(function (\Closure $set, $state) {
$newPublishDate = \Illuminate\Support\Carbon::createfromFormat("Y-m-d H:i:s", $state);

$this->isPublished = $newPublishDate < now();
}),
When the user changes the date in the picker, it crashes, and the form stops working:
48 Replies
ericmp #2
ericmp #2OP2y ago
toeknee
toeknee2y ago
where have you placed that DateTimePicker?
ericmp #2
ericmp #2OP2y ago
inside here:
protected function getFormSchema(): array
{
return [
// here
...
protected function getFormSchema(): array
{
return [
// here
...
toeknee
toeknee2y ago
And how have you rendered the page?
ericmp #2
ericmp #2OP2y ago
return view ('name of the view')->layout(layout::class) wdym
toeknee
toeknee2y ago
Ok what are you using in the layout view ? i.e. do you have the primary div
ericmp #2
ericmp #2OP2y ago
yes, all wrapped in a div ive discovered that also happens when i submit the form
public function save(): void
{
$this->notice->update($this->form->getState());

Notification::make()
->title(__('Éxito'))
->icon('heroicon-o-check')
->iconColor('success')
->send()
;
}
public function save(): void
{
$this->notice->update($this->form->getState());

Notification::make()
->title(__('Éxito'))
->icon('heroicon-o-check')
->iconColor('success')
->send()
;
}
<form
wire:submit.prevent="save"
>
{{ $this->form }}

... button type submit
<form
wire:submit.prevent="save"
>
{{ $this->form }}

... button type submit
toeknee
toeknee2y ago
I assume this is a custom livewire component and page outside of the filament panel?
ericmp #2
ericmp #2OP2y ago
i havent installed admin panel only forms ,, notifications & tables
toeknee
toeknee2y ago
Ok, so you need to ensure livewire is loaded, ideally in the head before the forms and components are. Also livewire components need to be wrapped i.e.
<div>
{{ $this->form }}

<form
wire:submit.prevent="save"
>
... button type submit
</div>
<div>
{{ $this->form }}

<form
wire:submit.prevent="save"
>
... button type submit
</div>
ericmp #2
ericmp #2OP2y ago
i said all is inside a div
toeknee
toeknee2y ago
You said, but your code showed otherwise. If providing snippets it's not helpful as it's a guessing game wihtout all the code as clearly you have a mistake somewhere.
ericmp #2
ericmp #2OP2y ago
in all other pages it works, livewire is loaded
toeknee
toeknee2y ago
Livewire can work loaded last and first, but that's not the issue the issue is the componetns are being triggered possibly before livewire is loaded.
ericmp #2
ericmp #2OP2y ago
why i clearly have a mistake? cant be a bug?
toeknee
toeknee2y ago
So it's best to load it first. It is extremely unlikely to be a bug.
ericmp #2
ericmp #2OP2y ago
not the first time i found bugs in filamentphp
toeknee
toeknee2y ago
Ok, bye.
ericmp #2
ericmp #2OP2y ago
but yeah what? lol
toeknee
toeknee2y ago
We are here offering help for free, if you're just going to argue opposed to listening and checking/providing code as per the #❓┊help then we will focus our time on people looking for help. Your implementation sounds very standard and unlikely to be a bug.
ericmp #2
ericmp #2OP2y ago
and that is the weird thing. i checked my code and compared it with other forms i have, and i cant understand what is going on i was just answering, not arguing opposed messages are only messages, depends on u how u read them. didnt mean to be agressive or something
toeknee
toeknee2y ago
Have you use the datetimepicker in other views?
ericmp #2
ericmp #2OP2y ago
yes but i think is something related when the component refreshes as i did reactive there, when changing it, it refreshed. so then crashed that is why then i said that when savig also crashes, cuz it refreshes the component if something is unclear just let me know ill try to explain it better
toeknee
toeknee2y ago
But you are jsut using reactive to refresh correct?
ericmp #2
ericmp #2OP2y ago
im using reactive there to get the new date and change a components variable depending on the date chosen
awcodes
awcodes2y ago
Can we see the whole livewire component blade. Based on what you posted you form isn’t even inside the form tags. I’m thinking you are missing a tag somewhere that is breaking livewires dom diffing.
toeknee
toeknee2y ago
This could be because you are adjusting the public properties outside of the livewire form. $this->isPublished try: $set('isPublished', true) as an example
ericmp #2
ericmp #2OP2y ago
ill try that, but id like to change the public property of my livewire component, not to create a new field in the form 1 sec
toeknee
toeknee2y ago
The way livewire works is it registers the properties and mounts them, when they change outside it causes all sorts of issues as they don't match up with what has been registered as I understand it. so you would tend to set it, maybe traverse outside of the form: $set('../isPublished', true)
LeandroFerreira
is there a mount method?
public function mount(): void
{
$this->form->fill();
}
public function mount(): void
{
$this->form->fill();
}
ericmp #2
ericmp #2OP2y ago
yep
public function mount(Notice $notice): void
{
$this->notice = $notice;

$this->isPublished = $this->notice->publish_date < now();

$this->form->fill($this->notice->toArray());
}
public function mount(Notice $notice): void
{
$this->notice = $notice;

$this->isPublished = $this->notice->publish_date < now();

$this->form->fill($this->notice->toArray());
}
is an edit-only form, not create okay i removed all other stuff not related to the error. i event only need a form field to make it crash. Component:
class NoticesForm extends Component implements Forms\Contracts\HasForms
{
use Forms\Concerns\InteractsWithForms;

public Notice $notice;

/**
* True if the notice is published.
*/
public bool $isPublished;

public function render()
{
return view('livewire.forms.notices-form')
->layout('mylayout');
}

public function mount(Notice $notice): void
{
$this->notice = $notice;

$this->isPublished = $this->notice->publish_date < now();

$this->form->fill($this->notice->toArray());
}

protected function getFormSchema(): array
{
return [
TextInput::make('title')->required()->maxLength(255),
];
}

protected function getFormModel(): Notice
{
return $this->notice;
}

public function submit(): void
{
$this->notice->update($this->form->getState());

$this->form->model($this->notice)->saveRelationships();

Notification::make()
->title(__('Éxito'))
->icon('heroicon-o-check')
->iconColor('success')
->send()
;
}
}
class NoticesForm extends Component implements Forms\Contracts\HasForms
{
use Forms\Concerns\InteractsWithForms;

public Notice $notice;

/**
* True if the notice is published.
*/
public bool $isPublished;

public function render()
{
return view('livewire.forms.notices-form')
->layout('mylayout');
}

public function mount(Notice $notice): void
{
$this->notice = $notice;

$this->isPublished = $this->notice->publish_date < now();

$this->form->fill($this->notice->toArray());
}

protected function getFormSchema(): array
{
return [
TextInput::make('title')->required()->maxLength(255),
];
}

protected function getFormModel(): Notice
{
return $this->notice;
}

public function submit(): void
{
$this->notice->update($this->form->getState());

$this->form->model($this->notice)->saveRelationships();

Notification::make()
->title(__('Éxito'))
->icon('heroicon-o-check')
->iconColor('success')
->send()
;
}
}
view:
<div>
{{ $this->form }}
<button type="button" wire:click="submit">submit</button>
</div>
<div>
{{ $this->form }}
<button type="button" wire:click="submit">submit</button>
</div>
ericmp #2
ericmp #2OP2y ago
when i submit:
ericmp #2
ericmp #2OP2y ago
wdym inside the form tags? ah i understand, u mean the html tags> no, i do have them, but for the example i wrote it fast. next time ill write it fine, without the ... just did put ... to say that i skip parts, but yeah that wasnt clear sorry
awcodes
awcodes2y ago
I understood that. But you showed {{ $this->form }} above your opening form tag. 🙂
ericmp #2
ericmp #2OP2y ago
fack, sorry let me edit it anyways, for the new example im not using form, just button wireclick
LeandroFerreira
can you share the layout code?
awcodes
awcodes2y ago
Based on what you’ve shown I’m not sure. Typically that error gets thrown due to dom diffing issue. Alpine is loosing track of the livewire component.
ericmp #2
ericmp #2OP2y ago
too big, what do u need to know about it? if it is useful to u, in other views i have using same layout, forms & tables work just fine
awcodes
awcodes2y ago
If you put the picker in another form that is working, does it break.?
ericmp #2
ericmp #2OP2y ago
it doesnt the datepicker is, lets say, the way i found the error but not the error itself here
LeandroFerreira
if you dont want to declare all properties, you need to use
public $data;
protected function getFormStatePath(): string
{
return 'data';
}
public $data;
protected function getFormStatePath(): string
{
return 'data';
}
or
public bool $isPublished;
public string $title;
public bool $isPublished;
public string $title;
ericmp #2
ericmp #2OP2y ago
isPublished is not a property of the model is just a boolean i created. the property would be publish_date ill try that anyways
LeandroFerreira
you have TextInput::make('title) but it isnt declared you should do public string $title;
ericmp #2
ericmp #2OP2y ago
just did it. i added public string $title;. but im getting exact same error :/
LeandroFerreira
did you try it?
public $data;
protected function getFormStatePath(): string
{
return 'data';
}
public $data;
protected function getFormStatePath(): string
{
return 'data';
}
because if you have a title in the form, you should do this:
$this->form->fill([
'title' => $notice->title
]);
$this->form->fill([
'title' => $notice->title
]);
if you are passing all fields, you need to declare or use $data
ericmp #2
ericmp #2OP2y ago
i added this:
public $data;

protected function getFormStatePath(): string
{
return 'data';
}
public $data;

protected function getFormStatePath(): string
{
return 'data';
}
now works!!!! leandro, thanks!!! and thanks y'all appreciete ur time 🙏
LeandroFerreira
Nice.. you can do this: $this->form->fill($this->notice->toArray()); But you need to declare all properties or forget it and use $data
ericmp #2
ericmp #2OP2y ago
final code:
class NoticesForm extends Component implements Forms\Contracts\HasForms
{
use Forms\Concerns\InteractsWithForms;

public Notice $notice;

/**
* True if the notice is published.
*/
public bool $isPublished;

public $data;

protected function getFormStatePath(): string
{
return 'data';
}

public function render()
{
return view('livewire.forms.notices-form')
->layout('mylayout');
}

public function mount(Notice $notice): void
{
$this->notice = $notice;

$this->isPublished = $this->notice->publish_date < now();

$this->form->fill($this->notice->toArray());
}

protected function getFormSchema(): array
{
return [
TextInput::make('title')->required()->maxLength(255),
];
}

protected function getFormModel(): Notice
{
return $this->notice;
}

public function submit(): void
{
$this->notice->update($this->form->getState());

$this->form->model($this->notice)->saveRelationships();

Notification::make()
->title(__('Éxito'))
->icon('heroicon-o-check')
->iconColor('success')
->send()
;
}
}
class NoticesForm extends Component implements Forms\Contracts\HasForms
{
use Forms\Concerns\InteractsWithForms;

public Notice $notice;

/**
* True if the notice is published.
*/
public bool $isPublished;

public $data;

protected function getFormStatePath(): string
{
return 'data';
}

public function render()
{
return view('livewire.forms.notices-form')
->layout('mylayout');
}

public function mount(Notice $notice): void
{
$this->notice = $notice;

$this->isPublished = $this->notice->publish_date < now();

$this->form->fill($this->notice->toArray());
}

protected function getFormSchema(): array
{
return [
TextInput::make('title')->required()->maxLength(255),
];
}

protected function getFormModel(): Notice
{
return $this->notice;
}

public function submit(): void
{
$this->notice->update($this->form->getState());

$this->form->model($this->notice)->saveRelationships();

Notification::make()
->title(__('Éxito'))
->icon('heroicon-o-check')
->iconColor('success')
->send()
;
}
}

Did you find this page helpful?