Closed antonkulaga closed 6 years ago
@antonkulaga This was removed, it was called impure.value
; see #43.
However, you can implemented like this (it is used in testing), yourself, if you really want it.
And it got removed for a very good reason: there is no "current value" of a Rx
.
If you are used to an API that doesn't honor referential transparency you might be surprised than (?)
is -1
and not 3
in this example:
val source = Var(0)
val odd = source.keepIf(_ % 2 == 1)(-1)
odd.impure.foreach(println) // prints -1
source := 2 // (nothing)
source := 3 // prints 3
source := 4 // (nothing)
println(odd.impure.value) // prints (?)
(In Scala.Rx filter has a weird semantics, it would happily give you 0
as the first value of odd
, but that's an orthogonal problem.)
The reason for that behavior is that every call to impure.foreach
does a complete interpretation of the Rx graph, which is completely independent of whether someone else is already "listening" to that Rx or not.
It happens quite often when you want to read current values of Rx-es, for instance, you are sending a message to the server (via websocker or ajax) and you want to get all values of the fields inside the message form that is connected with UI via Rx[String] Maybe you can just make an "unsafe" package with implicits? So, people who need this feature will use it, but will understand that it can lead to some strange corner-cases
I think I didn't give you a good example. It's not that "getting the current value" is unsafe or wrong, but rather than there is no such thing as the current value of a Rx.
Let me try to answer your question with another question. What would expect as the "current value" of count
in this example:
val source: Var[Int] = Var(1)
val count = source.foldp(0)(_ + _)
source := 1
source := 1
source := 1
println(count.currentValue) // ?
What about in this example:
val source: Var[Int] = Var(1)
source := 1
source := 1
source := 1
println(source.foldp(0)(_ + _).currentValue) // ?
@antonkulaga I haven't worked with an entire form in monadic-html (that I can remember), but I think it would be similar to something like this:
val currentUrl = Var(URI.create(defaultUrl))
def app: (Node, Rx[URI]) = {
val div =
<div>
<input type="text" placeholder={prompt}
id = {formId} />
<button onclick={ (ev: dom.Event) => {
val text: String = ev.target match {
case elem: dom.Element => elem.parentNode.childNodes.toIterable
.find(child => child.nodeName === "INPUT") match {
case Some(elem: html.Input) => elem.value.trim
case None => defaultUrl
case _ =>
println(s"Error: unrecognized element for SpecifyUri($formId)")
defaultUrl
}
case _ => println("Event error!")
defaultUrl
}
currentUrl := URI.create(text)
}}>OK</button>
</div>
But instead of only updating one Var
in the handler (currentUrl
), you might have several you need to update. Ultimately, that html is mounted into the page, which runs any Rx
s present in the mounted HTML, computing their value (to distinguish from the non-existent current value).
Actually, now that I think about it, that could get rather tedious for many inputs, though I guess that could be abstracted to some extent by by extracting the case elem
to a function.
@bbarker it is A LOT of boilerplate! When I used Scala.Rx what I did is just got .now values (for monadix html I have an ugly workaround that works only for Vars and involves creating an implicit class that gets value of [mhtml] var cacheElem) and it was very convenient, here you propose to do DOM traversal that negates all the advantages of Rx-es.
@antonkulaga Scala.Rx provides a .now
method at the cost of memory leaks and a non referentially transparent API. Nothing's wrong with that, it's just a different design :). As I said before there is no such things as the current value of a mhtml.Rx
, and the concept will never ever exist.
Now if you are interested, I can try to explain why this is the case, how things work in mhtml APIs, and also, given a concrete use case for .now
, how to reformulate it without a .now
.
In Scala.Rx there was useful .now method that allowed to know current value of Rx/Var from outside, please, implement it!