Skip to content

Commit

Permalink
Docs: 17.1.0 blog post draft
Browse files Browse the repository at this point in the history
  • Loading branch information
raquo committed Jul 12, 2024
1 parent 76dfa7f commit 2304213
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 0 deletions.
118 changes: 118 additions & 0 deletions website/blog/2024-08-01-laminar-v17.1.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
---
title: Laminar v17.1.0 & stickers
author: Nikita
authorURL: https://twitter.com/raquo
---

New Airstream features: splitting Vars, and zooming into Vars without an owner.

<!--truncate-->

> Laminar is a Scala.js library for building web application interfaces and managing UI state. Learn more in [a few short examples](https://demo.laminar.dev) or [one long video](https://www.youtube.com/watch?v=L_AHCkl6L-Q).

## Releases

* [Laminar](https://github.com/raquo/laminar) 17.1.0
* [Airstream](https://github.com/raquo/airstream) 17.1.0


## 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.

```scala
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](https://github.com/kitlangton) has [figured out](https://github.com/raquo/Airstream/issues/119) 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` and `findUpdate`. **Migration:** if you have custom instances of `Splittable` for non-standard collection types, make sure to review the default implementations of those methods for efficiency.


## 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](https://docs.google.com/forms/d/e/1FAIpQLSdxwtT0-Yy9mxcyYoNPUwinAMzAojGviAY-pp8KARnf_NLxKA/viewform).

<img src="/img/blog/laminar_stickers_1000.jpg" />


## Thank you

Laminar development is kindly supported by [my sponsors](https://github.com/sponsors/raquo), and I am very grateful to be able to work on all this.


<h4 class="x-like-h3">DIAMOND sponsor:</h4>

<div class="-sponsorsList x-alignItemsStart x-justifyContentCenter">
<div class="-sponsor x-diamond x-company x-heartai">
<a class="x-noHover" href="https://www.heartai.net/">
<img class="-logo" src="/img/sponsors/heartai.svg" alt="" />
<div class="-tagline"><u>HeartAI</u> is a data and analytics platform for digital health and clinical care.</div>
</a>
</div>
</div>

**GOLD sponsors**:

<div class="-sponsorsList x-alignItemsEnd">
<div class="-sponsor x-person x-yurique">
<img class="-avatar x-rounded" src="/img/sponsors/yurique.jpg" alt="" />
<div class="-text">
<div class="-name"><a href="https://github.com/yurique">Iurii Malchenko</a></div>
</div>
</div>
<div class="-sponsor x-company x-aurinko">
<a class="x-noHover" href="https://www.aurinko.io/">
<img class="-logo" src="/img/sponsors/aurinko-light-250px.png" alt="" />
<div class="-tagline"><u>Aurinko</u> is an API platform for workplace addons and integrations.</div>
</a>
</div>
<a class="-sponsor x-person x-tawasal" href="https://tawasal.ae">
<img class="-avatar" src="/img/sponsors/tawasal.svg" alt="" />
<div class="-text">
<div class="-name">Tawasal</div>
<div class="-description">Secure multi-purpose messenger and superapp, offering free voice, text, video conferencing and lifestyle services.</div>
</div>
</a>
<div class="-sponsor x-empty">
<!-- filler for layout purposes -->
</div>
</div>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 2304213

Please sign in to comment.