Fork me on GitHub
Mark Wardle06:07:14

Hi all. I'm starting to use form state, and it is working well, but entered data persists, even after the current user logs out. Therefore, I'm copying the pattern in the fulcro demo to clear state on componentDidMount. The data is clearly initialised, and my textfield clears, but the date component does not. I'm using a StringBufferedInput here, but the data is the db is "", so it should have cleared? Should I be using component local state for this kind of pattern? It may make more sense and I'm overcomplicating things using this pattern?

Mark Wardle09:07:36

When I navigate away and back, the field is cleared, so I assume my UI isn't refreshing properly, perhaps because the value isn't changing. Clearly my client db has the right data so I think it is a refresh issue.


it would be easier perhaps to nuke most of the app state on logout

👍 1

and navigate to some start screen

Jakub Holý (HolyJak)12:07:42

If the db has the correct data and the ui shows state data then it is often due to a missing link somewhere between Root and your component either in queries or in data.

👍 1

OK, so nil is not a valid value, and SBI might not work properly in that case. I don’t know if I tested for that. Log the value of that date on renders and see if you see it coming in as nil, but still rendering the other way. Inputs in React are a bit of a pain (as I’ve explained many times and in videos). Technically a date type input has to have a string as its real value, and an empty string in order to show nothing. The “buffered” part of the SBI has to do with the fact that I have to use local state to track and compare incoming async changes from those that the input has done to itself through the mutability of the browser input itself (controlled by C++ code in the browser, I mean). It’s a real @#*$-show. Could be that the functions being used with SBI to do the conversions between desired type and strings are not doing the right thing as well. My guess is that if you log the data being rendered that you’ll see the correct values. If that is incorrect, then there’s a need to fix your logic (but I don’t see any immediate problem there). If you are seeing the correct values logged but the wrong things rendered, then it is in SBI. Check that your function to go from input value (local date) to string will give “” on nil and not nil.

👍 1

One other comment on forms: Forms have a lifecycle. form-state is about data tracking, but there is a lot more to form interaction than that (obviously), Having a UISM that goes with forms is very helpful (which is part of what led to RAD…it basically just gives you a lot of those bits as pluggable parts).

👍 1
Mark Wardle15:07:06

Thanks all - really helpful advice. My UILocalDate component is logging the value. On first use, it is nil (1); my usage of SBI does include turning nil into "" as part of :model->string As I type, I get the values updating nicely (2). I then navigate away, and navigate back. The NHS number form is cleared, but the date shows the old value. (3) The log outputs twice - the first with the date, the second as nil. So if I navigate away again, and come back, both fields are clear (4). So my interpretation is that the log shows the value is being cleared, but only after the date control is displayed. Not entirely sure whether I should be worried I'm getting two log outputs from a component and whether that might be a reason. I've tried to avoid RAD so far because I'm still learning the basics here, and keen to understand how it works.

Mark Wardle16:07:37

@roklenarcic I would probably like to do that anyway, to be sure that I don't persist anything from one session to another. If I reset state to {} in a mutation, I get a complaint from routing, so how does one nuke state and yet preserve the internals without having to resort to re-loading/re-mounting?

Mark Wardle16:07:45

@U0522TWDA thanks - I think I have the wiring correct, because the text field containing the NHS number is being correctly wiped, even though it logs a value and then an empty string - the log here shows NHS number and date of birth with values, and then both empty, and yet the display of date of birth doesn't change. A nil date is turned into "" as part of StringBufferedInput :model->string, but the empty string isn't updating the UI. Perhaps I can force refresh that control, as it may be a funny thing with HTML5 dates... I will check with another browser as well!

Jakub Holý (HolyJak)16:07:45

For nuking the state - you could either replace it with (comp/initial-state Root) or manually delete all keys not starting with com.fulcrologic. Perhaps...

Mark Wardle16:07:18

Thanks. I will try that and do some more debugging of the StringBufferedInput - which did itself solve a prior problem with handling typing in the date field when I previously just naively used a HTML5 date input mapping to and from strings in :value and :onChange.

Mark Wardle20:07:55

I have fixed the issue by simply making sure I use set-value!! and not set-value! in my onChange handler for this date component. Thanks all. 😀

Jakub Holý (HolyJak)20:07:51

Awesome! Thanks for sharing!


Yeah, the async nature of the single ! combined with how the date field itself acts is the culprit. Using sync transactions just sidesteps the issue, so good.

👍 1
Mark Wardle06:07:16

Thank you very much. It is working nicely.

Mark Wardle06:07:55

Just a small update. This didn't work in the end, as I added more controls the problem with the date field recurred, although all other fields did get cleared. I assumed it was some weird html date refresh thing and got into a muddle until I realised I could simply clear the data in the willUnmount event and now it is all sorted. Sorry for the noise, but posted here in case affects someone else 😀

Toni Tuominen13:07:21

Is it possible to dev/test RAD forms and reports in isolation with If it is, what sort of setup do I need to do? Anyone have any examples?


Yes. RAD reports/forms normally rely on routing hooks to start, but both the report and form nses have start like functions to start up the form or report. So, you’d basically need to trigger those functions on component mount instead. You can actually add :componentDidMount to the report itself. For forms, you’ll need something as a wrapper, since you’ll either want to do “new” or “edit” something. You can also make a wrapper that includes a router, and route to them (without history installed).