2

I'm trying to use threepenny to learn about FRP.

I'd like to generate events that contain the user's input, and fire each time a button is clicked. You can see the code on github.

I've tried to do so with a function

submitEvents :: Element -> Element -> UI (Event String)
submitEvents button input = do val <- get value input
                               return $ val <$ (UI.click button)

And it's used later in a do block like so.

nameE <- submitEvents loginButton userNameInput
currName <- stepper "Ash" nameE
element currNameElem # sink text currName

But it ends up just becoming the empty string after the first click. Before then it contains the value "Ash" as expected. What I think is happening is that the value of the input is being extracted when I generate the event stream, instead of once per click. I looked around the docs, and didn't see anything to go from m a -> Event () -> m (Event a), but I'm rather new to frp, and may have missed something.

duplode
  • 33,731
  • 7
  • 79
  • 150
Theo Belaire
  • 2,980
  • 2
  • 22
  • 33
  • 1
    As you have already noted, the value `val` doesn't change over time, it's the value of the input widget at the time when `get` is called, i.e. when the event stream is constructed. You can also see this by looking at its type: `val :: String`, which is not something that can change over time. In contrast, `currName :: Behavior String`, which indicates a `String` that changes over time. – Heinrich Apfelmus Jan 12 '14 at 09:29

1 Answers1

1

Oh, I see. I'm constructing what I need from UI.valueChange.

submitEvents :: Element -> Element -> UI (Event String)
submitEvents button input = do currVal <- stepper "" $ UI.valueChange input
                               return $ currVal <@ (UI.click button)

works great. I'm not sure if there's a more efficient way that only looks at it when a button is pushed though. I'm leaving the question open in case anyone finds a better answer.

Theo Belaire
  • 2,980
  • 2
  • 22
  • 33
  • 1
    That's the canonical way to do it (as of threepenny-gui-0.4.*). The seeming inefficiency is a red herring, because the underlying JS implementation has to update the value with every key press anyway, so there is no way to "look only when the button is pushed". – Heinrich Apfelmus Jan 12 '14 at 09:35