What's new in Angular 18
Tags: angular, typescript, signals, javascript
Published: 2024-05-28 06:04:14

---
title: What's new in Angular 18
description: A study guide that helps you learn the new version of Angular
published: true
tags: #angular #typescript #signals #javascript
canonical_url: https://www.angularaddicts.com/whats-new-in-angular-18
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hbnp353ekvpvsqz5xhj3.png
---

Since I published my 
- [Master Angular 17 Study guide](https://www.angularaddicts.com/p/master-angular-17) , 
- [Master Angular 17.1 and 17.2 Study guide](https://www.angularaddicts.com/p/master-angular-17-1-and-17-2) and the
- [What's new in Angular 17.3](https://www.angularaddicts.com/p/whats-new-in-angular-17-3) article

the Angular team released a new major version: Angular 18.
## 🎯Changes and new features
In this article, I list out the most important changes and new features, also share resources that will teach you how these new Angular features work:

- Control flow syntax and defer blocks are now stable
- Angular Material 3 is now stable, [material.angular.io](http://material.angular.io/) is updated by the new themes and documentation
- Experimental change detection without ZoneJS: `provideZonelessChangeDetection`
- Unified control state change events
- Fallback content for `ng-content`
- Route redirect functions
- Coalescing is enabled by default
- `HttpClientModule` deprecation
- Typescript 5.4 support

Now [angular.dev](https://angular.dev/) is the official website for the Angular documentation.
### 📌Experimental change detection without ZoneJS: `provideZonelessChangeDetection`

**Official docs:** [Angular without ZoneJS (Zoneless)](https://angular.dev/guide/experimental/zoneless)
**Merge request / commit:** [feat(core): Add zoneless change detection provider as experimental](https://github.com/angular/angular/pull/55329)

Angular 18 introduces a new, zoneless way to trigger change detection. When using `provideExperimentalZonelessChangeDetection`, Angular will use use Angular APIs to schedule change detection, including:

 * `ChangeDetectorRef.markForCheck`
 * `ComponentRef.setInput`
 * Updating a signal that is read in a template
 * When bound host or template listeners are triggered
 * When attaching a view that was marked dirty by one of the above
 * When removing a view
 * When registering a render hook (templates are only refreshed if render hooks do one of the above)

You can try the zoneless change detection with the new `provideExperimentalZonelessChangeDetection` provider, and components using `OnPush` change detection strategy:

```typescript
 bootstrapApplication(App, { 
   providers: [
     provideExperimentalZonelessChangeDetection(),
   ]
 });
 ```

Angular CDK and Angular Material also introduced has zoneless support.
### 📌Unified control state change events
**Official docs:** [AbstractControl.events](https://angular.dev/api/forms/AbstractControl)
**Merge request / commit:** [feat(forms): Unified Control State Change Events](https://github.com/angular/angular/pull/54579)

In Angular 18, the `AbstractControl` class (the base class for `FormControl`, `FormGroup`, and `FormArray`) introduced a new `events: Observable<ControlEvent<TValue>>`  property. This property is an observable, that emits for value, status, pristine or touched changes.

```ts
@Component({
  selector: 'app-abstract-control-events',
  standalone: true,
  imports: [ReactiveFormsModule],
  template: ` <input [formControl]="titleInputControl" /> `,
})
export class AbstractControlEventsComponent {
  titleInputControl = new FormControl<string | null>('', Validators.required);
  constructor() {
    this.titleInputControl.events.pipe(takeUntilDestroyed()).subscribe(console.log);
  }
}
```

If you click on the input field in the example, enter a character, then click outside of the input field, the following events are logged on the browser's console:

```
PristineChangeEvent {pristine: false, source: FormControl2}
ValueChangeEvent {value: 'a', source: FormControl2}
StatusChangeEvent {status: 'VALID', source: FormControl2}
TouchedChangeEvent {touched: true, source: FormControl2}
```
### 📌Fallback content for `ng-content`

**Official docs:** [Content projection with ng-content](https://angular.dev/guide/components/content-projection)
**Merge request / commit:** [feat(core): add support for fallback content in ng-content](https://github.com/angular/angular/pull/54854)

In Angular 18, we can specify a fallback content for `<ng-content>`, this content is rendered when there is no content specified for projection in the parent component:

```ts
@Component({  
  selector: 'app-header',  
  template: `  
    <ng-content select=".title">Default tilte</ng-content>  
    <ng-content select=".explanation">There is no explanation for this title</ng-content>  
  `,  
})  
export class HeaderComponent {}

@Component({  
  selector: 'app-wrapper',  
  template: `  
    <app-header>  
      <span class="title">First chapter</span>  
    </app-header>
  `,  
})  
export class WrapperComponent {}
```

These components are rendered as:

```html
<app-wrapper>
  <app-header>
    <span class="title">First chapter</span>
    There is no explanation for this title  
  </app-header>
</app-wrapper>
```

### 📌Route redirect functions
**Official docs:** [Common router tasks: Setting up redirects](https://angular.dev/guide/routing/common-router-tasks#setting-up-redirects)
**Merge request / commit:** [feat(router): Allow Route.redirectTo to be a function which returns a string or UrlTree](https://github.com/angular/angular/pull/52606)

In Angular 18, a route's `redirectTo` property can be a function that returns a string or `UrlTree`, enabling us to create more dynamic redirects based on the application's state:

```ts
export const routes: Routes = [
  // ...,
  {
    path: "prods", //legacy path
    redirectTo: ({ queryParams }) => {
      const productId = queryParams['id'];      
      if (productId) {
        return `/products/${productId}`;
      } else {
        return `/`;
      }
    }
  },
  // ...,
];
```

### 📌Coalescing is enabled by default

**Official docs:** [NgZoneOptions](https://angular.dev/api/core/NgZoneOptions)

Starting from Angular 18, [zone coalescing](https://angular.dev/api/core/NgZoneOptions) is enabled by default (`eventCoalescing: true`) for newly created applications. Zone coalescing can reduce the number of the change detection cycles and improve the app's performance.

### 📌`HttpClientModule` deprecation

**Merge request / commit:**  [refactor(http): Deprecate HttpClientModule & related modules,Migration schematics for HttpClientModule](https://github.com/angular/angular/pull/54020)

Starting with v18, the preferred way of providing the HTTP client are `provideHttpClient()` and `provideHttpClientTesting()`. `HttpClientModule` and `HttpClientTestingModule` are deprecated now.

When you run `ng update @angular/core`, Angular can automatically migrate your code to use the preferred `provideHttpClient()` and `provideHttpClientTesting()` functions instead of the deprecated modules.

### 📌Typescript 5.4 support

**Merge request / commit:** [feat(compiler-cli): drop support for TypeScript older than 5.4](https://github.com/angular/angular/pull/54961)

[Daniel Rosenwasser](https://twitter.com/drosenwasser) highlighted the most interesting new features of Typescript 5.4 in his [announcement](https://devblogs.microsoft.com/typescript/announcing-typescript-5-4/):

- Preserved Narrowing in Closures Following Last Assignments
- The `NoInfer` Utility Type
- `Object.groupBy` and `Map.groupBy`
- Support for `require()` calls in `--moduleResolution bundler` and `--module preserve`
- Checked Import Attributes and Assertions
- Quick Fix for Adding Missing Parameters
- Auto-Import Support for Subpath Imports

## 👨‍💻About the author

My name is [Gergely Szerovay](https://www.linkedin.com/in/gergelyszerovay/), I worked as a data scientist and full-stack developer for many years, and I have been working as frontend tech lead, focusing on Angular-based frontend development. As part of my role, I'm constantly following how Angular and the frontend development scene in general is evolving.

Angular has advancing very rapidly over the past few years, and in the past year, with the rise of generative AI, our software development workflows have also evolved rapidly. In order to closely follow the evolution of AI-assisted software development, I decided to start building AI tools in public, and publish my progress on [AIBoosted.dev](https://aiboosted.dev) , [Subscribe here](https://aiboosted.dev) 🚀 

Follow me on [Substack (Angular Addicts)](https://www.angularaddicts.com/), [Substack (AIBoosted.dev)](https://aiboosted.dev), [Medium](https://medium.com/@GergelySzerovay), [Dev.to](https://dev.to/gergelyszerovay), [X](https://twitter.com/GergelySzerovay) or [LinkedIn](https://www.linkedin.com/in/gergelyszerovay/) to learn more about Angular, and how to build AI apps with AI, Typescript, React and Angular!