DEV Community

Cover image for Ng-News 25/47: Angular 21
ng-news for This is Angular

Posted on

Ng-News 25/47: Angular 21

Angular 21 is out. 3 new features stand out. @angular/aria, Vitest as stable testing framework and the absolute highlight: Signal Forms.

Signal Forms

With Signal Forms we have now finally one unique forms module, which is the successor of both Reactive and Template-Driven ones. Of course the old ones don't get deprecated.

As the name implies almost everything in Signals Forms is a Signal. Be it the field, the status, the value, the error, and so on.

import { Component, signal } from '@angular/core';
import { Field, form, required } from '@angular/forms/signals';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';

@Component({
  template: `<form (submit)="$event.preventDefault()">
    <mat-form-field>
      <mat-label>Firstname</mat-label>
      <input type="text" matInput [field]="userForm.firstname" />
    </mat-form-field>
    <mat-form-field>
      <mat-label>Lastname</mat-label>
      <input type="text" matInput [field]="userForm.lastname" />
    </mat-form-field>

    <button [disabled]="userForm().invalid()">Submit</button>
  </form>`,
  imports: [Field, MatFormFieldModule, MatInputModule],
})
export class NgNews {
  readonly #user = signal({
    id: 1,
    firstname: 'John',
    lastname: 'Smith',
  });

  protected readonly userForm = form(this.#user, (path) => {
    required(path.firstname);
    required(path.lastname);
  });
}
Enter fullscreen mode Exit fullscreen mode

Signal Forms are also very simple. You just take a Signal containing an object literal. That becomes the model which will be written in. You call the form function, pass it as first parameter and the second parameter is a callback function where you define your validation rules.

In the template, you write your typical html, and there is just one directive which is field that you to have add to the form fields.

And that's it. There is also magic anymore, as it was the old form modules where, the form tag, input tags and even html attributes got silently directives. Now it is really only the field directive and the rest is pure HTML.

That also means, that a form submit reloads the page, so be sure to cancel the submit event.

Signal Forms are released in experimental status but there were some statements, which indicate that it might enter developer preview soon.

Forms with signals • Angular

The web development framework for building modern apps.

favicon angular.dev

@angular/aria

There is a trend, away from UI Components which are fully designed and you can just take and use them right away, towards more having a set of minimalistic components which contain a solid foundation that you then use and come with up with your individual design.

In a way, that's the idea behind Angular Aria but it takes it to the limit and provides you with only an accessibility basis and all the rest can then be done by you.

Of course, Angular Material and CDK are still available, but they more stylistically opinionated.

Angular Aria • Overview • Angular

The web development framework for building modern apps.

favicon angular.dev

Vitest

Vitest is the new testing framework in Angular. To avoid confusion:. If you run ng new then you get Vitest. If you run ng update the testing framework will not be changed but there is a migration script which could help migrating from Jasmine to Vitest.

The API of Vitest and Jasmine are similar, the main differences are in the way how we mock dependencies and especially time. Jasmine has spies, whereas vitest also has in the form of vitest.fn. In terms of Vitest has fake timers, Jasmine uses jasmine.clock, whereas Vitest has useFakeTimers().

Here is an example in Jasmine:

import { TestBed } from '@angular/core/testing';

const dummyUser = { id: 1, name: 'John Smith' };

// Testing Example in Jasmine

describe('Ng-News Showcase', () => {
  it('should mock SecurityService', () => {
    const securityService = {
      get: jasmine.createSpy(),
    };
    securityService.get.and.returnValue(dummyUser);

    TestBed.configureTestingModule({
      providers: [{ provide: SecurityStore, useValue: securityService }],
    });
  });

  it('should fake the time', () => {
    const clock = jasmine.clock();
    clock.install();

    let a = 1;
    setTimeout(() => (a += 2), 1000);

    expect(a).toBe(1);
    clock.tick(1000);
    expect(a).toBe(2);

    clock.uninstall();
  });
});
Enter fullscreen mode Exit fullscreen mode

And here the same in Vitest:

import { TestBed } from '@angular/core/testing';
import { describe, it, expect, vitest } from 'vitest';

const dummyUser = { id: 1, name: 'John Smith' };

// Testing Example in Vitest

describe('Ng-News Showcase', () => {
  it('should mock SecurityService', () => {
    const securityService = {
      get: vitest.fn(),
    };
    securityService.get.mockReturnValue(dummyUser);

    TestBed.configureTestingModule({
      providers: [{ provide: SecurityStore, useValue: securityService }],
    });
  });

  it('should fake the time', () => {
    vitest.useFakeTimers();

    let a = 1;
    setTimeout(() => (a += 2), 1000);

    expect(a).toBe(1);
    vitest.advanceTimersByTime(1000);
    expect(a).toBe(2);

    vitest.useRealTimers();
  });
});
Enter fullscreen mode Exit fullscreen mode

So similar concepts but realistically, expect to manually migrate your tests.

Vitest is wrapped by the Angular CLI. That means not all configuration settings, plugins, tools or even IDE integrations will work. In case of doubt, consult the Angular documentation.

Migrating from Karma to Vitest • Angular

The web development framework for building modern apps.

favicon angular.dev

It is also worth noting, that fakeAsync and waitForAsync also don't work. So you have to use Vitest's useFakeTimers or expect.poll instead.

If you want to have the full Vitest experience, you would have to go with Analog's Vitest version, which is also the one that Nx is using.

Running Tests | Analog

Analog supports Vitest for running unit tests.

favicon analogjs.org

Further Features

Furthermore, resources are still experimental.

Angular 21 also brings improvements for its MCP server and much, much more.

As always there is a lot - especially for Signal Forms - community content out there, but the first target should be the official Angular blog post.

https://blog.angular.dev/announcing-angular-v21-57946c34f14b

Also be sure to checkout the Angular 21 release video, where the Angular presents the new features in the context of a classic video game which has similarities to Mario Land 3.

Top comments (0)