Widget taking Dynamic and returning Event

A common pattern in Reflex apps is that you write widgets which are rendered based on a Dynamic of some value (usually server-sent response), and then have the widget return an Event or some other value (eg: user button clicks).

documentEditor :: Dynamic t Document -> Event t (Id Document, Text)
documentEditor = 
  undefined

It is recommended to push the Dynamic to as deep as level as possible, where it actually gets used. So, if documentEditor is the place where it actually gets used, over there we would unpack the dynamic using the dyn function:

dyn :: (Adjustable t m, NotReady t m, PostBuild t m) => Dynamic t (m a) -> m (Event t a)

If we had a function Document -> m (Event t (Id Document, Text) that renders the document editor, along with returning the “save” event (of document ID and the user-entered text), then we can use dyn $ ffor ... to pass that input dynamic to it.

But in return we would get Event t (Event t (Id Document, Text)). How do we pull the final event out of it? This is where switchHold comes in handy.

switchHold :: (Reflex t, MonadHold t m) => Event t a -> Event t (Event t a) -> m (Event t a)

So for this particular pattern, it is common to call the widget using:

switchHold never <=< dyn $ ffor inputDyn $ \input -> do ...