## Where communities thrive

• Join over 1.5M+ people
• Join over 100K+ communities
• Free without limits
##### Activity
Nick Childers
@Voltir
I've been trying to tackle this problem - it's not the same issue as the flatmap problem. It also seems really hard to solve in a satisfying way.
Making futures compose nicely in Rx contexts is hard because the re-evaluation step recreates the future, creating the cycle of infinite loop
Roland Reckel
@rreckel
Call me crazy, but would it be possible to create a "toRx" function for Monix Task? Would that be easier perhaps, as those are lazy evaluated?
I guess I will have to look at the scala.rx code a bit.
Nick Childers
@Voltir
Sure - I think that's possible
Perhaps something akin to how sttp does its effect encoding https://github.com/softwaremill/sttp
I wouldn't want to add a dependency to monix in the core repo though
Roland Reckel
@rreckel
You are right.... adding a dependency is not good.
Nick Childers
@Voltir
What gives me hope is that toRx does appear to work if the definition is outside of the flatmap - I think if I can make the flatmap macro generate the equivalent of that, we might finally have a decent solution
Minghao Liu
@molikto
@  val a = Var(1)

a: Var[Int] = Var@70(1)

@

@ val b = Var(2)
b: Var[Int] = Var@6b(2)

@  val c = Rx { println("c triggered "+ ( a() + b()))}
c triggered 3
c: Rx.Dynamic[Unit] = Rx@2e(())

@

@ a.kill()

@ b() = 3
c triggered 4

@ a() = 5
c triggered 8
so seems kill() doesn't work on Var?
Nick Childers
@Voltir
@molikto ah, thats interesting - what happens if you dont do the b() = 3 step?
kill on a Var just clears the downstream listeners - Vars dont really have an owner. What I think happens is when you trigger a re-evaluation of c via b() = 3, the dependency c has on a is just recreated. I guess "kill" is kind of a misleading name for what actually happens on a Var.
Peng Li
@freewind
Hi guys, I have some questions when testing scala.rx code, and post a question here: https://stackoverflow.com/questions/49073908/how-to-test-vars-of-scala-rx-with-scalatest
Thanks for helping
Nick Childers
@Voltir
@freewind i took a stab at answering it, let me know if you want any clarification
Peng Li
@freewind
@Voltir Thanks for your answer! It gives me some idea and I changed my test using scalatest's AsyncTestSuite and the code is:
test("watchOrders") {
var result = List.empty[Order]
val stream = client.watchOrders()
val promise = Promise[Assertion]()
stream.fold(List.empty[Order]) {
case (acc, Some(elem)) =>
val result = elem :: acc
println("result size: " + result.size)
if (result.size == 4) promise.success({
assert(validateTheOrders(result))
})
result
}
promise.future
}
The good new is if the validateTheOrders(result) is passed, the test will pass and terminate as expected
But if the assertion is false, it will never stop, and the result size printed in console will be:
result size: 1
result size: 2
result size: 3
result size: 4
result size: 4
result size: 4
result size: 4
...
Peng Li
@freewind

@Voltir I just make it work inspired with the eventually method from haoyi's utest. Now I'm still using scalatest's SyncTestSuit, and the code is like:

  private def waitUntil[T](stream: Rx[T])(cond: T => Boolean, maxWait: Duration): T = {
val promise = Promise[T]()
val list = stream.now
if (cond(list)) {
promise.success(list)
}
}, 0L, 100L, TimeUnit.MILLISECONDS)
Await.result(promise.future, maxWait)
}

test("watchOrders") {
val stream = client.watchOrders()
val listRx: Rx[List[Order]] = stream.fold(List.empty[Order]) {
case (acc, Some(elem)) => elem :: acc
case (acc, _) => acc
}
val list = waitUntil(listRx)(_.size >= 4, 10.seconds)
assert(validateTheOrders(list))
}

It's working great now

Nick Childers
@Voltir
@/all scala.rx 0.4.0 was published
scalway
@scalway
@Voltir where? I cannot find sources.
Oh... there is still old documentation & there is no github release :).
moritz bust
@busti
Why do I have to have an implicit Owner in scope when using rx.fold()() in a class / trait, but not when I use it elsewhere? Can I avoid that somehow?
scalway
@scalway
This is how scala.rx fights against memory leaks
moritz bust
@busti
Well yes, but if I understand it correctly, the context is generated automagically via macros most of the time? When I use fold in a repl, I do not need to declare an ownership context...
Is it okay to just include an implicit val ctx = Ctx.Owner.save() in my class? I have seen that somewhere...
But unfortunately .save() lacks documentation.
moritz bust
@busti

In this example:

class Foo {
val a = Var(0)

val b = a.fold(1)(_ * _)
}

how do I obtain / define / pass an Ownership Context?
It just is not very clear to me.

Nick Childers
@Voltir
Pass it in as an implicit class param on Foo
moritz bust
@busti
@Voltir But where does that implicit come from? I am not using any rx's elsewhere...
Nick Childers
@Voltir
so, if you have some object:
object Main {
val foo = new Foo()
}
(magic macro stuff happens to make that possible)
if you are inside a class, then you can again make that outer class take an implicit ctx
if you know for sure that Foo (or the class that wraps it) is going to be instantiated a finite number of times, then its safe to use the "unsafe" owner ctx
moritz bust
@busti
That is what I wanted to know, thanks a lot!
sidnt
@sidnt
Weird: I've done import rx._ but my code says not found: value Obs in this code piece for providing the implicit conversion.
sidnt
@sidnt
moritz bust
@busti
How would I merge two rx's of the same type into a single one, that updates whenever either of the source Rx's updates?
It's using "scalarx" % "0.2.8", but latest is "0.4.0"
This is what I got so far:
implicit def rxFrag[T](r: Rx[T])(implicit dataCtx:  Ctx.Data, ev: T => Frag): Frag = {
import Ctx.Owner.Unsafe._

def rSafe: dom.Node = span(r()).render

var last = rSafe
r.triggerLater {
val newLast = rSafe
js.Dynamic.global.last = last
last.parentNode.replaceChild(newLast, last)
last = newLast
}

last
}
but now even the simplest code requires this implicit Ctx.Data...
Simon Morgan
@simon-morgan

@lihaoyi and other contributors, thank you for an excellent library. I'm more productive and concise than every I was with scalajs-react and scala.binding.

@lihaoyi will you be at ScalaDays Lausanne in a few weeks? Any one else who uses scala.rx going to be there? It would be great to meet up, discuss experiences and share a drink!! If you are interested, please post!!!

Kamil Kloch
@kamilkloch

Hi! I am struggling with generating table rows wrapped within Rx construct. The following code
scala
Rx {
for (row <- rows()) yield tr(...)
}

produces a sequence of tr elements wrapped within an extra span. This kills the table column layout. Thanks in advance for any tips!

Rx {
for (row <- rows()) yield tr(...)
}
Marc Grue
@marcgrue
Wrapping a single element should do the trick I think:
Rx {
tbody(
for (row <- rows()) yield tr(...)
)
}`