Skip to content

Instantly share code, notes, and snippets.

@lancewalton
Last active October 20, 2021 15:41
Show Gist options
  • Select an option

  • Save lancewalton/a56a91e16de9c03715e55bcc903ea120 to your computer and use it in GitHub Desktop.

Select an option

Save lancewalton/a56a91e16de9c03715e55bcc903ea120 to your computer and use it in GitHub Desktop.
Problem with Laminar StrictSignal.foldLeft where the accumulated value is an EventStream
import com.raquo.laminar.api.L
import com.raquo.laminar.api.L.*
import munit.FunSuite
import scala.collection.mutable
case class Foo(s: String)
case class Bar(s: String)
object Collector {
def apply[A](stream: EventStream[A], operations: () => Unit*): List[A] = {
val result: mutable.ListBuffer[A] = mutable.ListBuffer.empty
stream.foreach { a =>
result.prepend(a)
}(unsafeWindowOwner)
operations.foreach(_())
result.toList
}
}
object Interpreter {
def interpret(foo: Foo): EventStream[Bar] = EventStream.fromValue(Bar(foo.s))
def interpretAndReconcile(foo: Foo, bar: Bar): EventStream[Bar] = EventStream.fromValue(Bar(s"${foo.s}(${bar.s})"))
}
class SignalTransformer extends FunSuite {
def transform(foos: StrictSignal[Foo]): EventStream[Bar] =
foos
.foldLeft(Interpreter.interpret(_)) { case (accumulator: L.EventStream[Bar], foo: Foo) =>
println(foo) // Just making sure things are getting called as I expect
// The order of the parameters in this merge seems not to matter.
EventStream.merge(accumulator.flatMap(Interpreter.interpretAndReconcile(foo, _)), accumulator)
}
.changes
.flatten
test("StrictSignal") {
val foo1: Foo = Foo("1")
val foo2: Foo = Foo("2")
val foo3: Foo = Foo("3")
val foos: Var[Foo] = Var(foo1)
// I don't usually write tests with println. I'm just using munit to run this.
println(
Collector(
transform(foos.signal),
() => foos.set(foo2),
() => foos.set(foo3)
)
)
// What I get is:
// Foo(2) -- this is from the println in the foldLeft
// Foo(3) -- this is from the println in the foldLeft
//
// List(Bar(1), Bar(2(1))) -- this is from the collected output
// What I want is (ignoring the two 'Foo' output lines):
// List(Bar(1), Bar(2(1)), Bar(3(2(1))))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment