DEV Community

Cover image for Ng-News 25/45: Analog v2, Debouncing in SignalForms, Testing & Time
ng-news for This is Angular

Posted on

Ng-News 25/45: Analog v2, Debouncing in SignalForms, Testing & Time

Analog.js 2.0 brings Angular even closer to the Vite ecosystem. And we also get debouncing in Signal Forms and fresh testing guidance from Andrew Scott.

⚙️ Analog.js 2.0

Analog.js was created by Brandon Roberts as a meta-framework for Angular and was released in version 2.0.

A meta-framework extends a frontend framework with backend capabilities, like running data-fetching and processing on the server.
It also brings convention-based routing that follows the filesystem, plus several higher-level features you know from frameworks like Next.js or SvelteKit.

Apart from being a meta-framework, what really makes Analog stand out is its integration of Angular into Vite.

React, Vue, Svelte and many others have a Vite build plugin, which means Vite actually builds the application.

Vite-Powered Build with Vitest Use Case

Angular does not integrate into Vite as a plugin. It has its own build system.

Angular’s build system uses the Vite dev server and - like Vite - esbuild, but it is still not a Vite plugin.

Angular-Powered Build with Vitest Use Case

There is a huge ecosystem around Vite that you can only use if your framework is part of Vite’s plugin graph. And that is exactly what Analog does: It provides a Vite plugin for Angular.

Analog as Vite Plugin

Analog 2.0 comes with many additional features and a deeper integration of Angular’s resources.

🧮 Signal Forms: Debouncing

No week without news about the upcoming Signal Forms. One of the most discussed missing features has been debouncing.

Debouncing is used for autocomplete or async validation, where we don’t want to send an HTTP request on every keystroke, but only after the user stops typing for a moment.

It was often said that debouncing belongs to events, like the debounceTime operator in RxJS.

Signals represent state, not events, so Signals themselves are not the right place for it.

Since RxJS should become optional, should we write our own debouncing helpers? Fortunately not.

Debouncing will not be added to Signals, but to Signal Forms.

A debounce() rule will be part of the form schema, where we define validation rules.

feat(forms): add `debounce()` rule for signal forms #64929

The debounce() rule allows developers to control when changes to a form control are synchronized to the form model.

This feature necessitated some changes to FieldState:

  • controlValue is a new signal property that represents the current value of a form field and control.
  • value conceptually remains unchanged; however, its value may lag behind that of controlValue if a debounce() rule is applied.

The debounce() rule essentially manages when changes to controlValue are synchronized to value. The intent is that an expensive or slow validation rule can react to the debounced value, rather than a more frequently changing controlValue.

Directly updating value immediately updates controlValue, and cancels any pending debounced updates.

A field will automatically inherit the debounce rule of its parent, and can override that rule for itself. If multiple rules are applied to the same field (not including inherited ones), the latest enabled (if conditional) debounce rule will be used.

⏱️ Testing: Mock Clocks and Asynchronous Tasks

Quite fitting to the debouncing topic: Andrew Scott, from the Angular team, published an article on how to deal with asynchronous tasks in tests.

Since fakeAsync and waitForAsync don’t work in a zoneless world, we have to look at alternatives.

Andrew starts by explaining the current situation. Today, we rely on fake timers or mock clocks. These allow us to tweak the date, control asynchronous tasks, or move time forward.

He also explains the limitations.

Unlike fakeAsync, there is no way to mock native asynchronous tasks like Promises.

So we often have to mix async/await with mocking functions. And we often need to know exactly how far we should advance in time, which can feel like an implementation detail. If a feature uses a debounce time, I don't always want to know the exact duration just to write a test.

Andrew ends with an outlook on potential improvements. He presents the idea of an automatic clock that advances time automatically, so we don’t have to do anything manually. The Angular team is collaborating with existing testing frameworks, and more improvements are expected.

Handling Time and Mock Clocks in Tests | by Andrew Scott | Nov, 2025 | Angular Blog

In the realm of software testing, the concept of time can be a tricky one to manage, especially when dealing with asynchronous operations…

favicon blog.angular.dev

Top comments (0)