Nullable dates in spatie/laravel-settings
Can anyone provide a basic example of how to define a settings class with a nullable date property?
I have this:
and a Page which provides a form with
DateTimePicker::make('dateFrom')->seconds(false)->native(false);
but every time I try to save where there is a date set, I am getting an error saying:
Cannot assign string to property App\Settings\MySettings::$dateFrom of type ?DateTimeInterfaceFrom reading the docs, I can't tell what else would be required? The global cast for DateTimeInterface is set up per the docs and default config publication.
Solution:Jump to solution
I think that the problem is that you are saying the property has to be a Carbon/DateTime instance but your trying to set it as a string. Easyist thing to do would probably be to convert the string to a carbon instance.
```php
DateTimePicker::make('showFrom')
->label('Show From')...
12 Replies
It seems that casts just aren't running/working? With the global casters, it shouldn't try to assign a string to that property, should it?
Don't type it as DateTimeInterface (that's an interface so it won't be casting correctly). You need to type it as a class that uses DateTimeInterface. Something like DateTime or Carbon
@ConnorHowell I’ve tried both of those. Getting the same error.
I think it actually needs to be a string since that's how livewire handles it, then modal cast it to a DateTimeInferface?
can you dd() the string value. I"m wondering if the ->seconds(false) is making it an invalid dateTime string and cast is failing to convert it.
also why do you have 2 properties with the same name?
@awcodes Sorry for the delay. The duplicate property name was poor copy/paste on my part to show a minimal example.
I have modified the
fill
function in laravel-settings/src/Settings
to catch the TypeError
as follows:
The value I get out is when selecting the 24th Jan 2024 at midnight is 2024-01-24 00:00
. Appending the seconds(false)
call with ->format('Y-m-d H:i:s')
results in a full Y-m-d H:i:s
format: 2024-01-24 00:00:00
. I continue to get the same TypeError thrown.
Hang on - I can easily just share the two classes involved here without needing to obfuscate.
AnnouncementSettings:
ManageAnnouncement:
The up
function of the migration:
Solution
I think that the problem is that you are saying the property has to be a Carbon/DateTime instance but your trying to set it as a string. Easyist thing to do would probably be to convert the string to a carbon instance.
Interesting. That's done it. I completely understand why that is the case - wonder if this could somehow be abstracted away with some sort of sensible default behaviour for the users. The underlying library suggests that this isn't necessary, so I guess its the filament package that needs this handling.
Cheers!
if you want to do it with the settings package you'll need to define the cast in the class.
Ahhh, so the prop needs to be a string for that. Again - slightly at odds with the underlying package, but I get why. Wondering what the best approach is. Tempted to suggest the dehydrate method, because at least when you access the settings class at some other point the property is correctly typed.
yea, this is a tricky situation because theres no real model for the settings, so you can't just do a normal cast
Yeah - I think I'll go with the dehydrate method, that way I am only concerned with ever casting it between the two types when serialising/deserialising to and from the repository.
Thanks again.