Vaadin 25.1 and Signals API – Feedback & Discussion

Vaadin 25.1 is upcoming and we are planning to ship the production-ready UI state management API aka Signals API.

We are happy to announce that latest Vaadin 25.1 pre-release (25.1.0-alpha6) has already collected many new methods, classes and improvements, although it is not yet in a shape of final release, but will be soon.

We kindly ask anyone to try it out, any kind of feedback on the Signals API is appreciated:

  • API or design suggestions
  • Bugs or unexpected behavior
  • Real-world use cases
  • Documentation or clarity issues
  • Open discussion and questions

We’d recommend to start using Signals in a new code rather than for converting existing Vaadin codes, but either experience would be great to hear about.

Reference documentation is available here How to manage UI state with signals in Vaadin Flow
Vaadin version: 25.1.0-alpha6.

Even short feedback is valuable. If possible, please include a concrete example.

Description

Clearly describe your feedback.

  • What feels good or problematic?
  • What is confusing or missing?
  • What would you like to change or improve?

Use case

Describe the real-world scenario where this matters.

Why is this important in practice?
How would developers benefit from a change here?

Code example (if applicable)

Minimal reproduction or illustrative example.
Pseudocode is perfectly fine.

const count = signal(0);

effect(() => {
  console.log(count.value);
});

Expected behavior

Describe a behavior you expect from existing API in case I doesn’t work or look like you’d want.


Remember to vote feedback comments so it helps us to prioritize future work.

1 Like

:face_with_peeking_eye: Page not found (404)

Thanks, it was a dot in the end. Now works :)

  1. I don’t understand this section: Component Bindings with Signals in Vaadin Flow

What is the difference between using a lambda and an explicit computed (i.e., what does the lambda result in)? And what does “cache the result” mean concrete?

  1. Component Bindings with Signals in Vaadin Flow uses shared signals out of the sudden without an explanation. Is there a reason, that TWB needs shared signals or does it also work with normal signals?
1 Like

I am very interested in multithreading in particular. I often use Project Reactor.

I’ll take a look.

1 Like

Was ListSignal removed in alpha05?
It was still there in alpha03.

Thanks

I don’t fully understand why the “Shared” signals are needed.
I assumed that this was determined by Scope of where it is defined.
If defined in UI Scope, it would survive and work in that scope.
If it’s a singleton, then it would be shared server-wide.

Or is the shared idea mainly introduced to work across servers on a cluster?

thank you.

The original signal types from Vaadin 24.8 - 25.0 have two central characteristics:

  • They deal with concurrency by ensuring you use immutable values that are updated using fine-grained operations.
  • They have APIs that will make it possible to synchronize signal values across a cluster in the future.

This makes them appropriate for use cases with collaboration between multiple users but also inconvenient for other cases such as keeping track of which JPA entity a user has selected.

To have good support for both all kinds of usage, we introduce separate shared and local signal types. The original types are renamed as “shared” (e.g. SharedListSignal) and then we’re introducing new “local” signals (e.g. ValueSignal) that can also be used with mutable values. A “local” ListSignal has already been merged since we built the latest alpha version so it will be included in the next one.

1 Like

ValueSignal was renamed to SharedValueSignal and moved to the “shared” package.
But then we added a new “local” implementation of it with the same name ValueSignal, however, this unfortunately didn’t get into this latest alpha.

Please override Vaadin Flow version to 25.1.0-alpha6, where it is available, while we are baking next platform release:

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.vaadin</groupId>
                <artifactId>flow-bom</artifactId>
                <version>25.1.0-alpha6</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.vaadin</groupId>
                <artifactId>vaadin-bom</artifactId>
                <version>25.1.0-alpha5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
1 Like

Great!

Thank you @mikhail.21 and @Leif for the clarification.

I’ve went through the document thoroughly yesterday, because in about 2 hours I’m giving a Signals workshop to my colleagues :-) Best way to learn is to teach, right?

I made a sample application (Stormtrooper Battle Simulator … I have Star Wars fans in my team :rofl:) to demonstrate certain use-cases . I’ll publish it on GH after a bit of clean-up, maybe it can be useful for others as wel.

Btw, spoiler alert … YES … I can do “Pieuw Pieuw” in one user session, and be completely unharmed in another :rofl:

2 Likes
  1. The lambda variant will run the
    callback every time the signal value is read, it doesn’t cache the value of the computed signal (formed as lambda). Explicit computed signal on the other hand
    caches the result of running the callback until the value of any
    dependency (signal.value()) changes. In some cases like String::length it’s enough to use lambda because it’s a cheap operation, but for complex operations it’s better to use explicit computed signal.

Something to clarify in the docs.

  1. Seems no reason, perhaps a leftover after renamings. Two-way binding works with all signals that implement WritableSignal, so there is no difference in that regards. Let us correct the docs.

Nice to hear. What did your colleagues think?