reflex-frp / reflex

Interactive programs without callbacks or side-effects. Functional Reactive Programming (FRP) uses composable events and time-varying values to describe interactive systems as pure functions. Just like other pure functional code, functional reactive code is easier to get right on the first try, maintain, and reuse.
https://reflex-frp.org
BSD 3-Clause "New" or "Revised" License
1.07k stars 149 forks source link

getPostBuild seems to fire too fast? #488

Closed augyg closed 4 months ago

augyg commented 1 year ago

Recently I've faced a different issue when using Obelisk so the following is a hack around that issue (see: https://github.com/obsidiansystems/obelisk/issues/962) however this feels worth reporting.

The hack was using getPostBuild to force the page's HTML to render before the javascript to getUserMedia however with:

pb <- getPostBuild prerender_ blank $ performEvent_ ((liftJSM $ clog ("hey" :: T.Text)) <$ pb)

"hey" is never logged, but if I use delay like so:

p <- getPostBuild p' <- delay 0.00000000001 p

And instead use p' in-place of pb it works. I've played around with this number and If I make the time slightly smaller it has the same effect as before where the Event never "seems" to fire.

Partially motivated to reporting since it seems expected that getPostBuild would have this effect without delay, and I suspect the code (clog ~ console.log) hasn't been written yet given the tiny delay?

alexfmpe commented 1 year ago

Also curious how PostBuild and hydration switchover are supposed to interact. Does it work as intended if you do

prerender_ blank $ do
  pb <- getPostBuild
  performEvent_ ((liftJSM $ clog ("hey" :: T.Text)) <$ pb)
augyg commented 1 year ago

@alexfmpe your code actually works as intended

augyg commented 4 months ago

-- | Fire some logic right now and return result as an Event performPostBuildEvent :: (PostBuild t m, PerformEvent t m) => Performable m b -> m (Event t b) performPostBuildEvent f = getPostBuild >>= performEvent . (f <$)