Laminar v17.1.0, News & Stickers
New Airstream features: splitting Vars, and zooming into Vars without an owner.
Laminar is a Scala.js library for building web application interfaces and managing UI state. Learn more in a few short examples or one long video.
Releases
News
Scala.js & Laminar in Healthcare
The HeartAI team are using Scala.js and Laminar to develop their Critical Care Informatics System for CALHN, a major health network in South Australia. A key feature of this system, ICU ward and bed dashboards, support critical care workers with high-quality health information about ICU patients. "Scala.js and Laminar have provided a scalable way to build robust applications in the complex health domain." – says Lukah Dykes, Managing Director at HeartAI.
Laminar Stickers
In case you missed it, I'm mailing out free Laminar stickers as a thank you to people who have, in one way or another, contributed to Laminar or the ecosystem. Sign up here.
New Airstream Features
Splitting Var-s
You could always split
a Signal[Collection[A]]
into N individual Signal[A]
, but now you can also directly split a Var[Collection[A]]
into N individual Var[A]
that are linked to the original Var[Collection[A]]
.
For example, in the example below, the user's name in both userVar
and usersVar
is updated when you type the new name into the input text box.
case class User(id: String, name: String)
val usersVar = Var[List[User]](???)
div(
usersVar.split(_.id)((userId, initial, userVar) => {
div(
s"User ${userId}: ",
input(
value <-- userVar.signal.map(_.name),
onInput.mapToValue --> { newName =>
userVar.update(_.copy(name = newName))
}
)
)
})
)
Previously in this situation, you would have needed to update usersVar
manually by finding the user with id == userId
and updating the list with the new user at that index. Now this is done behind the scenes just by updating userVar
.
Also, in addition to split
, you can also use splitMutate
on Vars that contain mutable collections. As the name implies, it works the same as regular Var.split
, except that when you update userVar
, it would mutate the collection in usersVar
instead of creating a copy of it as is usually done with immutable collections. This may be more efficient when working with very large mutable collections.
Zoom into a Var without needing an Owner
Airstream has had the zoom
method to create derived vars for a while now: Var.zoom(a => b)((a, b) => a)(implicit owner)
. Unfortunately, that method required an Owner
, which made using it rather annoying.
Recently, @KitLangton has figured out that this Owner isn't really needed, and so we now have a new zoomLazy(a => b)((a, b) => a)
method that does not require an Owner
, and otherwise works pretty much the same. One catch is that your zoomIn
(a => b
) function is now called lazily, so it shouldn't have side effects. In practice that shouldn't be a problem because this function typically just selects some field from an object.
This small change should help a lot with ergonomics of local state management.
We use the zoomLazy
name to stay binary-compatible with 17.0.0 in this release, but in the next major release, zoomLazy
will be renamed to zoom
, and the old zoom
will be renamed to zoomStrict
and deprecated.
Small stuff
- New:
.not
alias to the.invert
operator on observables of booleans - The
Splittable
trait has two new methods:foreach
andfindUpdate
. Migration: if you have custom instances ofSplittable
for non-standard collection types, make sure to review the default implementations of those methods for efficiency.
Waypoint bug fix
- Waypoint upgraded to URL-DSL 6.0.2:
- Fixed a case with
listParam
where matching failed if no query parameters were provided in the URL, whereas it should have matched asNil
. Thanks, @arturaz!
- Fixed a case with
Thank you
Laminar development is kindly supported by my sponsors, and I am very grateful to be able to work on all this.
DIAMOND sponsor:
GOLD sponsors: