Description
Here's a minimal test case (as minimal as I could get it down to) running on v0.3.6
. The idea is to have a looping widget until a button is pressed (think a query form with some internal state) and then return that internal state to the parent widget.
So effWidget
shows a div
waiting on a mouse down event, performs a side effect, and then gets called again with a new b
, in this case just showing a div
without any attached events.
If the user clicks the "Query" button then query
returns with some value, which is then shown in queryTest
. The problem is that once the user clicks on the div
(which is a big rectangle) with the attached mouse down event the rectangle disappears, and pressing the "Query" button doesn't do anything.
Removing the side effect or swapping the children in query
(which just calls the orr
combinator afaics) fixes the problem, so I'm guessing this is some edge case interaction between Aff
and the evaluation of parallel branches (as far as I understand) in the Widget
monad. Do you have some other insight that might help?
effWidget :: Boolean -> Widget HTML Boolean
effWidget b = do
_ <- if b
then D.div [ P.style style ] []
else do
_ <- D.div [ P.onMouseDown, P.style style ] []
liftEffect $ log "Effect" -- if we remove this line everything works
pure (not b)
where
style =
{ position: "absolute"
, backgroundColor: "#777"
, top: "100px"
, left: "100px"
, width: "300px"
, height: "300px"
}
query :: Widget HTML Boolean
query = go false
where
go st = do
event <- D.div
[]
[ Left <$> effWidget st
, Right <$> D.button [ P.onClick ] [ D.text "Query" ] -- if this goes first everything works
]
case event of
Left st' -> go st'
Right _ -> pure st
queryTest :: ∀ a. Widget HTML a
queryTest = do
a <- query
D.text (show a)
main :: Effect Unit
main = runWidgetInDom "root" queryTest