OlivierBlanvillain / monadic-html

Tiny DOM binding library for Scala.js
https://olivierblanvillain.github.io/monadic-html/examples/
MIT License
225 stars 24 forks source link

Is there a reason there's no Rx.now() method? #120

Open tflucke opened 3 years ago

tflucke commented 3 years ago

Or something equivalent to this that would let you access the Rx's value once without using side-effects? The scala.rx library linked in the README and so does Binding.scala for Var's and within certain scopes.

In particular, I have a use case where I want to call an API using the current value. The best solution I can think of with the methods that are currently available would be something like this:

val x: Rx = ...
var tmp = 0
x.map({tmp = _})
val value = tmp

But this relies on side effect and is very non-functional and is very clunky.

tflucke commented 3 years ago

I ended up separating my solution out into a helper class which at least hides/limits the scope of the mutability:

implicit class RxHelpers[T](rx: Rx[T]) {
    private var _value: T

    rx.map(_value = _)

    def value = _value
}

I'm still curious if there's a reason this wasn't included in the original library.

I also have some concerns with whether or not his would generate a memory leak. Granted seeing as scala is a garbage collected language, I'm not sure how memory leaks could happen, but it seems like this has been a concern in other parts of the code.

OlivierBlanvillain commented 2 years ago

Sorry for the late answer. The idea is that in an idiomatic use case you would like calls your API to also be "reactive", that is, to trigger them again if the underlying value of your Rx changes. If that matches your use case, then you should extract the value in your Rx using .map instead.

The library's test suite defines a .value method in an implicit class, and that implementation should be free of memory leaks so you might want to use that instead (your implementation attaches a new callback on every .value call, which is going to monitor the Rx forever).

https://github.com/OlivierBlanvillain/monadic-html/blob/d6b5e34d8a2a414ffab20e35bd6e5f623e3fcb67/monadic-rx/shared/src/test/scala/mhtml/RxTests.scala#L7-L18