Datepicker - setting via code oddness

I am setting the date of a datepicker component in a few different ways and getting unexpected results.

I have a date_picker component which is linked to a date database table column. When i set it the “self.date_picker.date” to a date object when the form is created, the component correctly shows the date, but the form’s “item” does not update itself. When i save the form, and the app tries to show the new database record, I get an ugly error because the database has a “None” in the new record when it should be a date.

However, if i interact with the datepicker in the UI and select a date, the component updates the database when the form is saved.

Also, it works if i set the datepicker date from a record in my database in my code.

Compared with the other components, i can set the “selected values” of the other drop-down and text box components fine.

Is there something i’m missing to make sure that setting the date component in this way flows through to the database record as i expect it to?

I think we need a little more to nail down this issue. I’m sure it’ll be a small problem in the code. Could you put together a clone link that highlights just the issue you’re facing so we can dig around…

Hi sc549! Thanks, yes hopefully this works.

https://anvil.works/build#clone:TI265AFTFLPIZIFW=SBRJSEEFQZQL56CYXXU4PA6N

AddItem and FreezerContents forms.

I wonder if you can provide a smaller clone link that only highlights the problem you are facing - the one you provided has a lot of complexity and won’t actually run for me because it also has required dependencies…

In this example
A datepicker
A table with a date column
A form with a self.item and relevant databindings

Basically the minimum example that shows the issue

Then we’ll either be able to get to the bottom the code issue, or report a bug…

1 Like

Sure I should have some time tonight to do this.

https://anvil.works/build#clone:WY3FQMNK65PSPZGK=EX65JAG6CJ2U6OEKN7QAOVX3

Here you go. When i set the datepicker.date to a datetime.date object by code, i get the error “AttributeError: ‘NoneType’ object has no attribute ‘strftime’. Did you initialise all data binding sources before initialising this component?”
and the database column has a “None” in it, instead of the datetime.date.

In the Design interface on the datepicker component , i have a data binding to “date” and the name of the column in the data table. and writeback enabled.

so one of your rows in the database has a date of None

which means self.item['expiry_data'].strftime(...) won’t execute because NoneType has no attribute strftime.

You can either - ensure all data is complete before entering it into the datatable and/or include a fail safe in the data binding…

self.item['expiry_date'].strftime("%d %b %Y") if self.item['expiry_date'] is not None else self.item['expiry_date']

Thanks for your suggestion how to avoid the error, but this error is a consequence of the issue (datepicker component not working as expected, or I’m using it incorrectly) that I’m trying to get to the bottom of.

I am setting a default “selected value” for the datepicker component that the user can see in runtime. Most of the time it will be this default value and sometimes it won’t. The datepicker component doesn’t have a “selected value” attribute like the other components. But it has “date” which I think is the equivalent. So I’ve set the datepicker.date to a datetime.date object by code (which is then showed to the user in runtime as the default value). If the user leaves this component alone, I expect this to go into the database, rather that nothing or “None” going in there.

If the user wants to change the default date, and they use the datepicker component, it works as expected and the database updates.

In fact if the user just clicks on the datepicker component and keeps the date at the default value, the datepicker component works as expected.

In the first app i linked, if the user wants to edit a record in the database, the datepicker component starts with the date in the record - and the component works as expected if the user leaves the component alone.

Hopefully this explains things a bit better? I really appreciate you looking at this

Is it because in the design window, in properties, I haven’t set the “date”, and this is taking priority over my code to set the datepicker date in the code window? I don’t think i should set the date field in the design window, because the date I want to show will depend on if the user is adding a new item (default date is used) or if the user is editing an item (edited item date is used).

I see - makes sense

try

self.item = {'expiry_date': use_by_date_default}

in the __init__ method. (this way you’ve set the default date on the item and the databindings will just work)

The problem with the code example you’re working on is that writeback is not triggered by code.
In the datepicker example it’s only triggered when the date_changed event is fired
that’s why

self.date_picker.date = default_date

has no impact on self.item

some linked docs
https://anvil.works/docs/client/data-bindings#two-way-data-bindings

1 Like

Ah ok, this does explain the behaviour here. Thanks again :smile: