fulcrologic / fulcro-rad

Fulcro Rapid Application Development
MIT License
200 stars 46 forks source link

Ad hoc loaded picker options lose :cached-at timestamp #107

Open danskarda opened 1 year ago

danskarda commented 1 year ago

I experimented with "cascading entity pickers". Chosing one picker value loads other picker options, like Invoice line items in Fulcro RAD demo. In demo changing category (eg Toys), calls picker-options/load-options! and prepares subselection of items. Another example would be selecting User Account could provide list of available addresses for Address picker. I do not know if "cascading entity pickers" is correct term, but you got the picture. Changing one value will trigger picker-options/load-options! from :on-change form trigger.

In my application when user selects "Location", I query an external system for list of resources available at the location. The external system is kind of slow. So what I noticed is that the option cache is not utilized and options are always reloaded.

Result of picker options load is stored in ::picker-options/options-cache. I investigated the issue and found that option cache values contain :cached-at, :options and :query-result keys. While all other standard options were loaded correctly (think all-accounts and all-categories in fulcro-demo new invoice example), my picker options loaded later were missing :cached-at.

You can confirm the behavior in Fulcro Demo "New invoice" form. After changing Category, new item in option-cache is missing :cached-at. Here is a screenshot from Fulcro Inspect:

image

What I found is that load-picker-options! correctly sets the timestamp

https://github.com/fulcrologic/fulcro-rad/blob/ba17f5d3057a18e4af77294fc59b9408451896cd/src/main/com/fulcrologic/rad/picker_options.cljc#L81

And the change is visible in Fulcro Inspect DB history. Then later this record disappears. Probably during merging the result of load? When :post-action hook is invoked, it receives a state where its option-cache contains only :query-result. It adds transformed option, but :cached-at timestamp is lost.

I think setting timestamp before reloading is correct place, because it prevents multiple requests when the picker is reused multiple times on the page. But why is cached-options removed is beyond my knowledge of Fulcro (RAD) internals. I cannot even guess if it is a bug or expected behavior and result of load implementation.

What I would suggest is to assoc timestamp once more at the end of :post-action.

https://github.com/fulcrologic/fulcro-rad/blob/ba17f5d3057a18e4af77294fc59b9408451896cd/src/main/com/fulcrologic/rad/picker_options.cljc#L94

I can provide a pull request, but without further knowledge it would be only treating symptoms, not the root cause.

awkay commented 1 year ago

Probably a bug...I haven't had time to dig into this, but yes if the load includes the item in the query without a :ui/... namespace then merge will remove it (since the server won't respond with it).

What do the network exchanges look like? Is the cached-at going with the query?

danskarda commented 1 year ago

I used fulcro-rad-demo line_teim.forms.cljc as an example:

https://github.com/fulcrologic/fulcro-rad-demo/blob/c09d1c30482c63ca2b468c9a7789dd5e80604a50/src/shared/com/example/ui/line_item_forms.cljc#L35

Both my code and fulcro-rad-demo show the same behavior so you can use demo code for investigation.

fulcro-rad-demo makes a query [({::item/all-items [::item/id ...]} {:category/id #uuid "..."})]. No, cached-at does not go with a query.