What's new in Angular 15?

Angular 15.0.0 is here!

Angular logo

This is a major release with a ton of interesting features: let’s dive in!

Standalone components are stable! ✨

Here we are: standalone components are now stable! You can officially build Angular applications without modules if you want to.

Check out our guide to standalone components:

👉 A guide to standalone components in Angular

A few improvements landed in v15.

The HTTP support evolved, and we can now use provideHttpClient to provide HttpClient without using HttpClientModule (see below).

We can now use provideHttpClientTesting() to provide HttpClient in tests, and… provideLocationMocks() to test components using the router:

TestBed.configureTestingModule({
  providers: [
    // 👇 ~ similar to RouterTestingModule
    // (some providers are missing compared to RouterTestingModule)
    provideRouter([]), 
    provideLocationMocks(), 
    // 👇 similar to HttpClientTestingModule
    provideHttpClient(),
    provideHttpClientTesting()
  ],
});

The NgForOf directive is now aliased as NgFor which makes it simpler to import it in your standalone components, as you previously had to know ngIf was the NgIf directive, and ngFor was the NgForOf directive 😅.

The same kind of thing has been done with the RouterLink directive in the router: there was previously a RouterLink directive and a RouterLinkWithHref directive. They are now merged into one, making it a no-brainer to import it. A schematic will automatically migrate your code if you were using RouterLinkWithHref.

The language service (used for the autocompletion and type-checking in your IDE) has been improved for standalone components, and it now automatically offers to import a standalone directive/component/pipe in your component, if you use one in its template ✨.

HTTP with provideHttpClient

The HTTP support evolves and adapts to the new world of Angular 15, where modules are optional. It’s now possible to provide the HttpClient using provideHttpClient(). HTTP interceptors are also evolving and can now be defined as functions.

We wrote a dedicated article about this:

👉 HTTP in a standalone Angular application with provideHttpClient

Directive composition API

The other big feature of Angular v15 is the directive composition API. We also wrote a dedicated article about this:

👉 Directive Composition API in Angular

NgOptimizedImage is stable

The NgOptimizedImage directive is now stable and can be used in production. Introduced in Angular v14.2, it allows you to optimize images. You can check out our explanation in our blog post about v14.2.

Note that there is a change in the API: the NgOptimizedImage directive now has inputs named ngSrc and ngSrcset (whereas they were originally called rawSrc and rawSrcset).

<img [ngSrc]="imageUrl" />

Another input called sizes has also been added. When you provide it a value, then the directive will automatically generate a responsive srcset for you.

<img [ngSrc]="imageUrl" sizes="100vw"> />

It uses the default breakpoints [16, 32, 48, 64, 96, 128, 256, 384, 640, 750, 828, 1080, 1200, 1920, 2048, 3840] (and thus generates a big srcset with all these values) but they can be configured.

providers: [
  {
    provide: IMAGE_CONFIG, useValue: { breakpoints: [1080, 1200] }
  },
]

This generates the following srcset: https://example.com/image.png 1080w, https://example.com/image.png 1200w.

This behavior can be disabled via the disableOptimizedSrcset input of the directive.

The directive also gained a new fill boolean input, which removes the requirements for height and width on the image, adds inline styles to cause the image to fill its containing element and adds a default sizes value of 100vw which will cause the image to have a responsive srcset automatically generated:

<img [ngSrc]="imageUrl" fill />

Last but not least, the directive triggers the generation of a preload link in the head of your document for priority images when used in SSR/Angular Universal.

Dependency injection

The providedIn: NgModule syntax of the @Injectable() decorator is now deprecated. You generally want to use providedIn: 'root'. If providers should truly be scoped to a specific NgModule, use NgModule.providers instead. The providedIn: 'any' syntax is also deprecated.

Router

The router now auto-unwraps default exports from lazy-loaded modules, routes or components. You can replace:

loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule)
// of for routes
loadChildren: () => import('./admin/admin.routes').then(c => c.adminRoutes)
// or for component
loadComponent: () => import('./admin/admin.component').then(m => m.AdminComponent)

with the shorter:

loadChildren: () => import('./admin/admin.module')
// of for routes
loadChildren: () => import('./admin/admin.routes')
// or for component
loadComponent: () => import('./admin/admin.component')

if AdminModule, AdminComponent and adminRoutes are default exports.

Forms

Some utility functions have been added to the forms package: isFormControl, isFormGroup, isFormRecord, isFormArray.

They are particularly useful when you want to write a custom validator, as custom validators have AbstractControl in their signature, but you often know that the validator you write is for a specific FormControl, FormGroup, etc.

positiveValues(control: AbstractControl) {
  if (!isFormArray(control)) {
    return null;
  }
  // check that every value is positive
  // we can use `control.controls` here \o/
  if (control.controls.some(c => c.value < 0)) {
    return { positiveValues: true };
  }
  return null;
}

Common

Angular v13 introduced the toke DATE_PIPE_DEFAULT_TIMEZONE to configure the default timezone of the DatePipe (see our blog post about v13).

This token has been deprecated in v15 and replaced with DATE_PIPE_DEFAULT_OPTIONS which accepts an object with a timezone property and a dateFormat property to specify the default date format that the pipe should use.

providers: [{ provide: DATE_PIPE_DEFAULT_OPTIONS, useValue: { dateFormat: 'shortDate'} }]

Devtools

The devtools now allow you to inspect the source code of a directive

Angular CLI

As usual, you can check out our dedicated article about the new CLI version:

👉 Angular CLI v15

Summary

This release is packed with features as you can see, and the future is exciting with the standalone APIs. The roadmap includes work on the CLI to be able to generate standalone applications without modules. It also mentions some efforts on the server-side rendering story, which is not the strong suit of Angular (compared to other mainstream frameworks) and the possibility to use Angular without zone.js.

That’s all for this release, stay tuned!

All our materials (ebook, online training and training) are up-to-date with these changes if you want to learn more!



blog comments powered by Disqus