-
-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add debouncing example #256
Add debouncing example #256
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great, I love it! 🎉
I have approved because it's good enough as it is, and I'm delighted to have the contribution. I have however, also left some comments for your consideration. Mostly style points to encourage people to use best practices. The only comment that might be a technical issue, is that I think you need to reset the debouncer once you release the value.
case _ => | ||
Sub.None | ||
|
||
final case class Model(value: String, debouncer: Option[(String, Int)]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(String, Int)
Only if you want to: It would be interesting to model the debouncer more intentionally and see what it does to your code, something like (I'm making this up, untested, probably incomplete etc):
final case class Debouncer(value: String, timeout: Int, timeRemaining: Int):
def reset: Debouncer = Debouncer("", timeout, timeout)
def update(timePassed): Debouncer = Debouncer(value, timeout, timeRemaining - timePassed)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
final class Debouncer[A](val value: A, timeRemaining: Int):
def update(timePassed: Int): Debouncer[A] =
Debouncer(value, timeRemaining - timePassed)
def isSteady = timeRemaining <= 0
I've implemented something like this (+ necessary changes in other parts of code; the model now has debouncer: Option[Debouncer[String]]
). I haven't pushed this changes, because to be honest I'm not sure if it's better than the original example (in terms of being easy to follow). Some logic is better encapsulated, but subscriptions
and update
definitions still need to be aware of the Debouncer
and actively manage it's state.
Perhaps something like onInput(Msg.UpdateValue(_)).debounced(100.millis)
, with no additional logic in subscriptions
and update
, would be ideal (if I remember correctly, in Laminar the API is similar to this). Before writing the example I tried to come up with something like this (possibly involving some changes to Tyrian itself), but for now I haven't had an idea nor enough time :( Hence I decided to at least provide an example, as a proof of concept.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but subscriptions and update definitions still need to be aware of the Debouncer and actively manage it's state.
Yes, that's expected, it's part of how the Elm architecture scales that, if you want to use this pattern, you just need to accept it and go along with it. However you construct a "component" like this, you always have to manually tie it into the various systems that will update it, somehow. But as I say, that's ok, it's just part of the pattern and you get used to it.
But I also think not including it is completely fine. If this version is easier to follow, that's totally ok with me. Thanks for giving it a shot! 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Recently I've been thinking how to add debouncing to an input using Tyrian. I've managed to find a good example in Elm. Perhaps something more declarative would be better, but I think this simple example is a good start. If there are any suggestions, I'll be happy to hear them.