(0) Here’s my understanding of the situation. Disclaimer. I know something about logic and formal methods, but am a newcomer to programming Elm. If I get something wrong, I’ll learn something new.
This is a long post, in part because I first summarise previous valuable statements from other contributions. Steps (11) and (12) give a demo of some key ideas.
(1) There are two problems here that require a solution. One is the user experience. The other is the design and implementation of the app.
(2) There are two states (of the
Model) here. One is the
state that was passed to
view to generate the HTML that the user sees (or screen reads etc). The user can change that HTML, by typing into a text box. Call this
(3) The other state is the one most recently returned to Elm by the
update function. Call this the
(4) Due to lag and timing issues, the two states may not be in strict lockstep. Relevant (and surprising) here is Lockstep - Wikipedia.
(5) Suppose the
view_state contains a
PressOnce button that vanishes after it is pressed. If the user is quick, or is a robot, the view can send two
PressOnce messages to
(6) Here’s the result of Never Trust User Input - Google Search.
update method in the Elm app should have an appropriate level of mistrust of the messages sent to it from the
view generated HTML. Each
state and so each
view_state has a version / sequence number.
(8) Having the view HTML return this version number as part of every message might help the
update message to be appropriately suspicious. The
update could treat the version number as a security token which can expire.
(9) What is appropriate user experience depends on the context. In some situations, presenting a Modal window - Wikipedia is the right thing to do. Wikipedia says
A modal window creates a mode that disables the main window but keeps it visible, with the modal window as a child window in front of it. Users must interact with the modal window before they can return to the parent application.
(10) A banking app might present a modal window whose HTML can generate only two messages, namely
Cancel. This might be inappropriate in a gaming app.
(11) While typing this message, Discourse shows at the foot of the page an OK, Buffering or Blank icon. Perhaps this is a visual indication of the the mismatch if any between what I’ve been calling the
view_state and the
(12) If you draft a reply to this message, you’ll have a demonstration of what I mean. You don’t have to send the draft message.