W3cubDocs

/Angular

Deprecated APIs and features

Angular strives to balance innovation and stability. Sometimes, APIs and features become obsolete and need to be removed or replaced so that Angular can stay current with new best practices, changing dependencies, or changes in the (web) platform itself.

To make these transitions as easy as possible, APIs and features are deprecated for a period of time before they are removed. This gives you time to update your applications to the latest APIs and best practices.

This guide contains a summary of noteworthy Angular APIs and features that are currently deprecated. See the full changelog for comprehensive details on deprecations and breaking changes.

Features and APIs that were deprecated in v6 or earlier are candidates for removal in version 9 or any later major version. For information about Angular's deprecation and removal practices, see Angular Release Practices.

For step-by-step instructions on how to update to the latest Angular release, use the interactive update guide at update.angular.io.

Index

To help you future-proof your projects, the following table lists all deprecated APIs and features, organized by the release in which they are candidates for removal. Each item is linked to the section later in this guide that describes the deprecation reason and replacement options.

Deprecated features that can be removed in v11 or later

Area API or Feature Deprecated in May be removed in
@angular/core DefaultIterableDiffer v7 v11
@angular/core defineInjectable v8 v11
@angular/core entryComponents v9 v11
@angular/core ANALYZE_FOR_ENTRY_COMPONENTS v9 v11
@angular/forms ngModel with reactive forms v6 v11
@angular/upgrade @angular/upgrade v8 v11
@angular/upgrade getAngularLib v8 v11
@angular/upgrade setAngularLib v8 v11
polyfills reflect-metadata v8 v11
template syntax <template> v7 v11

Deprecated features that can be removed in v12 or later

Area API or Feature Deprecated in May be removed in
@angular/core/testing TestBed.get v9 v12
@angular/core/testing async v9 v12

Deprecated features that can be removed in v14 or later

Area API or Feature Deprecated in May be removed in
@angular/forms FormBuilder.group legacy options parameter v11 v14

Deprecated features that can be removed in v15 or later

Area API or Feature Deprecated in May be removed in
@angular/compiler-cli Input setter coercion v13 v15
@angular/compiler-cli fullTemplateTypeCheck v13 v15
@angular/core Factory-based signature of ApplicationRef.bootstrap v13 v15
@angular/core PlatformRef.bootstrapModuleFactory v13 v15
@angular/core Factory-based signature of ViewContainerRef.createComponent v13 v15
@angular/upgrade Factory-based signature of downgradeModule v13 v15
template syntax bind-, on-, bindon-, and ref- v13 v15

Deprecated features that can be removed in v16 or later

Area API or Feature Deprecated in May be removed in
@angular/common/http/testing TestRequest accepting ErrorEvent for error simulation v13 v16
@angular/core getModuleFactory v13 v16
@angular/core ModuleWithComponentFactories v13 v16
@angular/core Compiler v13 v16
@angular/core CompilerFactory v13 v16
@angular/core NgModuleFactory v13 v16
@angular/core ComponentFactory v13 v16
@angular/core ComponentFactoryResolver v13 v16
@angular/core CompilerOptions.useJit and CompilerOptions.missingTranslation config options v13 v16
@angular/platform-browser-dynamic JitCompilerFactory v13 v16
@angular/platform-browser-dynamic RESOURCE_CACHE_PROVIDER v13 v16
@angular/platform-server ServerTransferStateModule v14 v16
@angular/service-worker SwUpdate#activated v13 v16
@angular/service-worker SwUpdate#available v13 v16

Deprecated features that can be removed in v17 or later

Area API or Feature Deprecated in May be removed in
@angular/common NgComponentOutlet.ngComponentOutletNgModuleFactory v14 v17
@angular/common DatePipe - DATE_PIPE_DEFAULT_TIMEZONE v15 v17
@angular/core NgModule and 'any' options for providedIn v15 v17
@angular/core @Component.moduleId v16 v17
@angular/router RouterLinkWithHref directive v15 v17
@angular/router Router writeable properties v15.1 v17
@angular/router Router CanLoad guards v15.1 v17
@angular/router class and InjectionToken guards and resolvers v15.2 v17

Deprecated features that can be removed in v18 or later

Area API or Feature Deprecated in May be removed in
@angular/common isPlatformWorkerApp and isPlatformWorkerUi v16 v18
@angular/core EnvironmentInjector.runInContext v16 v18
@angular/platform-server PlatformConfig.baseUrl and PlatformConfig.useAbsoluteUrl config options v16 v18
@angular/platform-server platformDynamicServer v16 v18
@angular/platform-browser BrowserModule.withServerTransition v16 v18
@angular/platform-browser makeStateKey, StateKey and TransferState, symbols were moved to @angular/core v16 v18

Deprecated features with no planned removal version

Area API or Feature Deprecated in May be removed in
template syntax /deep/, >>>, and ::ng-deep v7 unspecified

For information about Angular Component Development Kit (CDK) and Angular Material deprecations, see the changelog.

Deprecated APIs

This section contains a complete list all deprecated APIs, with details to help you plan your migration to a replacement.

TIP: In the API reference section of this site, deprecated APIs are indicated by strikethrough. You can filter the API list by Status: deprecated.

@angular/common

API Replacement Deprecation announced Details
NgComponentOutlet.ngComponentOutletNgModuleFactory NgComponentOutlet.ngComponentOutletNgModule v14 Use the ngComponentOutletNgModule input instead. This input doesn't require resolving NgModule factory.
DatePipe - DATE_PIPE_DEFAULT_TIMEZONE { provide: DATE_PIPE_DEFAULT_OPTIONS, useValue: { timezone: '-1200' } v15 Use the DATE_PIPE_DEFAULT_OPTIONS injection token, which can configure multiple settings at once instead.
isPlatformWorkerApp and isPlatformWorkerUi None v16 These two functions have no purpose since the removal of the webworker platform (they only return false). They can be safely removed.

@angular/core

API Replacement Deprecation announced Details
DefaultIterableDiffer n/a v4 Not part of public API.
defineInjectable ɵɵdefineInjectable v8 Used only in generated code. No source code should depend on this API.
entryComponents none v9 See entryComponents
ANALYZE_FOR_ENTRY_COMPONENTS none v9 See ANALYZE_FOR_ENTRY_COMPONENTS
async waitForAsync v11 The async function from @angular/core/testing has been renamed to waitForAsync in order to avoid confusion with the native JavaScript async syntax. The existing function is deprecated and can be removed in a future version.
getModuleFactory getNgModuleById v13 Ivy allows working with NgModule classes directly, without retrieving corresponding factories.
ViewChildren.emitDistinctChangesOnly / ContentChildren.emitDistinctChangesOnly none (was part of issue #40091) This is a temporary flag introduced as part of bug fix of issue #40091 and will be removed.
Factory-based signature of ApplicationRef.bootstrap Type-based signature of ApplicationRef.bootstrap v13 With Ivy, there is no need to resolve Component factory and Component Type can be provided directly.
PlatformRef.bootstrapModuleFactory PlatformRef.bootstrapModule v13 With Ivy, there is no need to resolve NgModule factory and NgModule Type can be provided directly.
ModuleWithComponentFactories none v13 Ivy JIT mode doesn't require accessing this symbol. See JIT API changes due to ViewEngine deprecation for additional context.
Compiler none v13 Ivy JIT mode doesn't require accessing this symbol. See JIT API changes due to ViewEngine deprecation for additional context.
CompilerFactory none v13 Ivy JIT mode doesn't require accessing this symbol. See JIT API changes due to ViewEngine deprecation for additional context.
NgModuleFactory Use non-factory based framework APIs like PlatformRef.bootstrapModule and createNgModule v13 Ivy JIT mode doesn't require accessing this symbol. See JIT API changes due to ViewEngine deprecation for additional context.
Factory-based signature of ViewContainerRef.createComponent Type-based signature of ViewContainerRef.createComponent v13 Angular no longer requires component factories to dynamically create components. Use different signature of the createComponent method, which allows passing Component class directly.
ComponentFactory Use non-factory based framework APIs. v13 Since Ivy, Component factories are not required. Angular provides other APIs where Component classes can be used directly.
ComponentFactoryResolver Use non-factory based framework APIs. v13 Since Ivy, Component factories are not required, thus there is no need to resolve them.
CompilerOptions.useJit and CompilerOptions.missingTranslation config options none v13 Since Ivy, those config options are unused, passing them has no effect.
providedIn with NgModule Prefer 'root' providers, or use NgModule providers if scoping to an NgModule is necessary v15 none
providedIn: 'any' none v15 This option has confusing semantics and nearly zero usage.
EnvironmentInjector.runInContext runInInjectionContext v16 runInInjectionContext is a more flexible operation which supports element injectors as well
@Component.moduleId none v16

@angular/core/testing

API Replacement Deprecation announced Details
TestBed.get TestBed.inject v9 Same behavior, but type safe.
async waitForAsync v10 Same behavior, but rename to avoid confusion.

@angular/router

API Replacement Deprecation announced Details
RouterLinkWithHref directive Use RouterLink instead. v15 The RouterLinkWithHref directive code was merged into RouterLink. Now the RouterLink directive can be used for all elements that have routerLink attribute.
provideRoutes function Use ROUTES InjectionToken instead. v15 The provideRoutes helper function is minimally useful and can be unintentionally used instead of provideRouter due to similar spelling.
setupTestingRouter function Use provideRouter or RouterModule instead. v15.1 The setupTestingRouter function is not necessary. The Router is initialized based on the DI configuration in tests as it would be in production.
class and InjectionToken guards and resolvers Use plain JavaScript functions instead. v15.2 Functional guards are simpler and more powerful than class and token-based guards.

@angular/platform-browser

API Replacement Deprecation announced Details
BrowserModule.withServerTransition No replacement needed. v16.0 The APP_IDtoken should be used instead to set the application ID.
makeStateKey, StateKey and TransferState Import from @angular/core. v16.0 Same behavior, but exported from a different package.

@angular/platform-browser-dynamic

API Replacement Deprecation announced Details
JitCompilerFactory none v13 This symbol is no longer necessary. See JIT API changes due to ViewEngine deprecation for additional context.
RESOURCE_CACHE_PROVIDER none v13 This was previously necessary in some cases to test AOT-compiled components with View Engine, but is no longer since Ivy.

@angular/platform-server

API Replacement Deprecation announced Details
ServerTransferStateModule No replacement needed. v14.1 The TransferState class is available for injection without importing additional modules during server side rendering, when ServerModule is imported or renderApplication function is used for bootstrap.
PlatformConfig.baseUrl and PlatformConfig.useAbsoluteUrl config options none v16 This was previously unused.
platformDynamicServer Import @angular/compiler and replace the usage with platformServer instead. v16 This is done to decrease the server bundle size for AOT builds.

@angular/forms

API Replacement Deprecation announced Details
ngModel with reactive forms FormControlDirective v6 none
FormBuilder.group legacy options parameter AbstractControlOptions parameter value v11 none

@angular/service-worker

API Replacement Deprecation announced Details
SwUpdate#activated SwUpdate#activateUpdate() return value v13 The return value of SwUpdate#activateUpdate() indicates whether an update was successfully activated.
SwUpdate#available SwUpdate#versionUpdates v13 The behavior of SwUpdate#available can be rebuilt by filtering for VersionReadyEvent events on SwUpdate#versionUpdates

@angular/upgrade

API Replacement Deprecation announced Details
All entry points @angular/upgrade/static v5 See Upgrading from AngularJS.

@angular/upgrade/static

API Replacement Deprecation announced Details
getAngularLib getAngularJSGlobal v5 See Upgrading from AngularJS.
setAngularLib setAngularJSGlobal v5 See Upgrading from AngularJS.
Factory-based signature of downgradeModule NgModule-based signature of downgradeModule v13 The downgradeModule supports more ergonomic NgModule-based API (versus NgModule factory based API).

Deprecated features

This section lists all deprecated features, which includes template syntax, configuration options, and any other deprecations not listed in the Deprecated APIs section. It also includes deprecated API usage scenarios or API combinations, to augment the information above.

Web Tracing Framework integration

Angular previously supported an integration with the Web Tracing Framework (WTF) for performance testing of Angular applications. This integration has not been maintained and is now defunct. As a result, the integration was deprecated in Angular version 8, and due to no evidence of any existing usage, removed in version 9.

/deep/, >>>, and ::ng-deep component style selectors

The shadow-dom-piercing descendant combinator is deprecated and support is being removed from major browsers and tools. As such, in v4, Angular's support for /deep/, >>>, and ::ng-deep was deprecated. Until removal, ::ng-deep is preferred for broader compatibility with the tools.

For more information, see /deep/, >>>, and ::ng-deep in the Component Styles guide.

bind-, on-, bindon-, and ref- prefixes

The template prefixes bind-, on-, bindon-, and ref- have been deprecated in v13. Templates should use the more widely documented syntaxes for binding and references:

  • [input]="value" instead of bind-input="value"
  • [@trigger]="value" instead of bind-animate-trigger="value"
  • (click)="onClick()" instead of on-click="onClick()"
  • [(ngModel)]="value" instead of bindon-ngModel="value"
  • #templateRef instead of ref-templateRef

<template> tag

The <template> tag was deprecated in v4 to avoid colliding with a DOM element of the same name (such as when using web components). Use <ng-template> instead. For more information, see the Ahead-of-Time Compilation guide.

ngModel with reactive forms

Support for using the ngModel input property and ngModelChange event with reactive form directives has been deprecated in Angular v6 and can be removed in a future version of Angular.

Now deprecated:

<input [formControl]="control" [(ngModel)]="value">
this.value = 'some value';

This support was deprecated for several reasons. First, developers found this pattern confusing. It seems like the actual ngModel directive is being used, but in fact it's an input/output property named ngModel on the reactive form directive that approximates some, but not all, of the directive's behavior. It allows getting and setting a value and intercepting value events, but some ngModel features, such as delaying updates withngModelOptions or exporting the directive, don't work.

In addition, this pattern mixes template-driven and reactive forms strategies, which prevents taking advantage of the full benefits of either strategy. Setting the value in the template violates the template-agnostic principles behind reactive forms, whereas adding a FormControl/FormGroup layer in the class removes the convenience of defining forms in the template.

To update your code before support is removed, decide whether to stick with reactive form directives (and get/set values using reactive forms patterns) or switch to template-driven directives.

After (choice 1 - use reactive forms):

<input [formControl]="control">
this.control.setValue('some value');

After (choice 2 - use template-driven forms):

<input [(ngModel)]="value">
this.value = 'some value';

By default, when you use this pattern, you get a deprecation warning once in dev mode. You can choose to silence this warning by configuring ReactiveFormsModule at import time:

imports: [
  ReactiveFormsModule.withConfig({warnOnNgModelWithFormControl: 'never'})
],

Alternatively, you can choose to surface a separate warning for each instance of this pattern with a configuration value of "always". This may help to track down where in the code the pattern is being used as the code is being updated.

Router class and InjectionToken guards and resolvers

Class and injection token guards and resolvers are deprecated. Instead, Route objects should use functional-style guards and resolvers. Class-based guards can be converted to functions by instead using inject to get dependencies.

For testing a function canActivate guard, using TestBed and TestBed.runInInjectionContext is recommended. Test mocks and stubs can be provided through DI with {provide: X, useValue: StubX}. Functional guards can also be written in a way that's either testable with runInInjectionContext or by passing mock implementations of dependencies. For example:

export function myGuardWithMockableDeps(
  dep1 = inject(MyService),
  dep2 = inject(MyService2),
  dep3 = inject(MyService3),
) { }

const route = {
  path: 'admin',
  canActivate: [myGuardWithMockableDeps]
}

This deprecation only affects the support for class and InjectionToken guards at the Route definition. Injectable classes and InjectionToken providers are not deprecated in the general sense. That said, the interfaces like CanActivate, CanDeactivate, etc. will be deleted in a future release of Angular. Simply removing the implements CanActivate from the injectable class and updating the route definition to be a function like canActivate: [() => inject(MyGuard).canActivate()] is sufficient to get rid of the deprecation warning.

Functional guards are robust enough to even support the existing class-based guards through a transform:

import {CanMatchFn} from '@angular/router';

function mapToCanMatch(providers: Array<Type<{canMatch: CanMatchFn}>>): CanMatchFn[] {
  return providers.map(provider => (...params) => inject(provider).canMatch(...params));
}
const route = {
  path: 'admin',
  canMatch: mapToCanMatch([AdminGuard]),
};

That is to say that guards can continue to be implemented as classes and then converted to functions at the route definition.

Public Router properties

None of the public properties of the Router are meant to be writeable. They should all be configured using other methods, all of which have been documented.

The following strategies are meant to be configured by registering the application strategy in DI via the providers in the root NgModule or bootstrapApplication:

  • routeReuseStrategy
  • titleStrategy
  • urlHandlingStrategy

The following options are meant to be configured using the options available in RouterModule.forRoot or provideRouter and withRouterConfig.

  • onSameUrlNavigation
  • paramsInheritanceStrategy
  • urlUpdateStrategy
  • canceledNavigationResolution
  • errorHandler

The following options are deprecated in entirely:

  • malformedUriErrorHandler - URI parsing errors should be handled in the UrlSerializer instead.
  • errorHandler - Subscribe to the Router events and filter for NavigationError instead.

CanLoad guards

CanLoad guards in the Router are deprecated in favor of CanMatch. These guards execute at the same time in the lifecycle of a navigation. A CanMatch guard which returns false will prevent the Route from being matched at all and also prevent loading the children of the Route. CanMatch guards can accomplish the same goals as CanLoad but with the addition of allowing the navigation to match other routes when they reject (such as a wildcard route). There is no need to have both types of guards in the API surface.

loadChildren string syntax

When Angular first introduced lazy routes, there wasn't browser support for dynamically loading additional JavaScript. Angular created its own scheme using the syntax loadChildren: './lazy/lazy.module#LazyModule' and built tooling to support it. Now that ECMAScript dynamic import is supported in many browsers, Angular is moving toward this new syntax.

In version 8, the string syntax for the loadChildren route specification was deprecated, in favor of new syntax that uses import() syntax.

Before:

const routes: Routes = [{
    path: 'lazy',
    // The following string syntax for loadChildren is deprecated
    loadChildren: './lazy/lazy.module#LazyModule',
  }];

After:

const routes: Routes = [{
    path: 'lazy',
    // The new import() syntax
    loadChildren: () => import('./lazy/lazy.module').then(m => m.LazyModule)
  }];

Version 8 update: When you update to version 8, the ng update command performs the transformation automatically. Prior to version 7, the import() syntax only works in JIT mode (with view engine).

Declaration syntax: It's important to follow the route declaration syntax loadChildren: () => import('...').then(m => m.ModuleName) to allow ngc to discover the lazy-loaded module and the associated NgModule. You can find the complete list of allowed syntax constructs here. These restrictions will be relaxed with the release of Ivy since it'll no longer use NgFactories.

Dependency on a reflect-metadata polyfill in JIT mode

Angular applications, and specifically applications that relied on the JIT compiler, used to require a polyfill for the reflect-metadata APIs.

The need for this polyfill was removed in Angular version 8.0 (see #14473), rendering the presence of the polyfill in most Angular applications unnecessary. Because the polyfill can be depended on by third-party libraries, instead of removing it from all Angular projects, we are deprecating the requirement for this polyfill as of version 8.0. This should give library authors and application developers sufficient time to evaluate if they need the polyfill, and perform any refactoring necessary to remove the dependency on it.

In a typical Angular project, the polyfill is not used in production builds, so removing it should not impact production applications. The goal behind this removal is overall simplification of the build setup and decrease in the number of external dependencies.

@ViewChild() / @ContentChild() static resolution as the default

See the dedicated migration guide for static queries.

@ContentChild() / @Input() used together

The following pattern is deprecated:

@Input() @ContentChild(TemplateRef) tpldeprecated !: TemplateRef<any>;

Rather than using this pattern, separate the two decorators into their own properties and add fallback logic as in the following example:

@Input() tpl !: TemplateRef<any>;
@ContentChild(TemplateRef) inlineTemplate !: TemplateRef<any>;

Cannot assign to template variables

In the following example, the two-way binding means that optionName should be written when the valueChange event fires.

<option *ngFor="let optionName of options" [(value)]="optionName"></option>

However, in practice, Angular ignores two-way bindings to template variables. Starting in version 8, attempting to write to template variables is deprecated. In a future version, we will throw to indicate that the write is not supported.

<option *ngFor="let optionName of options" [value]="optionName"></option>

Binding to innerText in platform-server

Domino, which is used in server-side rendering, doesn't support innerText, so in platform-server's domino adapter, there was special code to fall back to textContent if you tried to bind to innerText.

These two properties have subtle differences, so switching to textContent under the hood can be surprising to users. For this reason, we are deprecating this behavior. Going forward, users should explicitly bind to textContent when using Domino.

wtfStartTimeRange and all wtf* APIs

All of the wtf* APIs are deprecated and will be removed in a future version.

entryComponents and ANALYZE_FOR_ENTRY_COMPONENTS no longer required

Previously, the entryComponents array in the NgModule definition was used to tell the compiler which components would be created and inserted dynamically. With Ivy, this isn't a requirement anymore and the entryComponents array can be removed from existing module declarations. The same applies to the ANALYZE_FOR_ENTRY_COMPONENTS injection token.

NOTE: You may still need to keep these if building a library that will be consumed by a View Engine application.

ModuleWithProviders type without a generic

Some Angular libraries, such as @angular/router and @ngrx/store, implement APIs that return a type called ModuleWithProviders (typically using a method named forRoot()). This type represents an NgModule along with additional providers. Angular version 9 deprecates use of ModuleWithProviders without an explicitly generic type, where the generic type refers to the type of the NgModule. In a future version of Angular, the generic will no longer be optional.

If you're using the CLI, ng update should migrate your code automatically. If you're not using the CLI, you can add any missing generic types to your application manually. For example:

Before:

@NgModule({
/* ... */
})
export class MyModule {
  static forRoot(config: SomeConfig): ModuleWithProviders {
    return {
      ngModule: SomeModule,
      providers: [
        {provide: SomeConfig, useValue: config}
      ]
    };
  }
}

After:

@NgModule({
/* ... */
})
export class MyModule {
  static forRoot(config: SomeConfig): ModuleWithProviders<SomeModule> {
    return {
      ngModule: SomeModule,
      providers: [
        {provide: SomeConfig, useValue: config}
      ]
    };
  }
}

Input setter coercion

Since the strictTemplates flag has been introduced in Angular, the compiler has been able to type-check input bindings to the declared input type of the corresponding directive. When a getter/setter pair is used for the input, the setter might need to accept more types than the getter returns, such as when the setter first converts the input value. However, until TypeScript 4.3 a getter/setter pair was required to have identical types so this pattern could not be accurately declared.

To mitigate this limitation, it was made possible to declare input setter coercion fields in directives that are used when type-checking input bindings. However, since TypeScript 4.3 the limitation has been removed; setters can now accept a wider type than what is returned by the getter. This means that input coercion fields are no longer needed, as their effects can be achieved by widening the type of the setter.

For example, the following directive:

@Component({
})
export class SubmitButtonComponent {
  static ngAcceptInputType_disabled: boolean|'';

  private disabledValue = false;

  @Input()
  get disabled(): boolean {
    return this.disabledValue;
  }
  set disabled(value: boolean) {
    this.disabledValue = (value === '') || value;
  }
}

can be refactored as follows:

@Component({
})
export class SubmitButtonComponent {
  private disabledValue = false;

  @Input()
  get disabled(): boolean {
    return this.disabledValue;
  }

  set disabled(value: boolean|'') {
    this.disabledValue = (value === '') || value;
  }
}

fullTemplateTypeCheck

When compiling your application using the AOT compiler, your templates are type-checked according to a certain strictness level. Before Angular 9 there existed only two strictness levels of template type checking as determined by the fullTemplateTypeCheck compiler option. In version 9 the strictTemplates family of compiler options has been introduced as a more fine-grained approach to configuring how strict your templates are being type-checked.

The fullTemplateTypeCheck flag is being deprecated in favor of the new strictTemplates option and its related compiler options. Projects that currently have fullTemplateTypeCheck: true configured can migrate to the following set of compiler options to achieve the same level of type-checking:

{
  "angularCompilerOptions": {
    …
    "strictTemplates": true,
    "strictInputTypes": false,
    "strictNullInputTypes": false,
    "strictAttributeTypes": false,
    "strictOutputEventTypes": false,
    "strictDomEventTypes": false,
    "strictDomLocalRefTypes": false,
    "strictSafeNavigationTypes": false,
    "strictContextGenerics": false,
    …
  }
}

JIT API changes due to ViewEngine deprecation

In ViewEngine, JIT compilation required special providers (such as Compiler or CompilerFactory) to be injected in the app and corresponding methods to be invoked. With Ivy, JIT compilation takes place implicitly if the Component, NgModule, etc. have not already been AOT compiled. Those special providers were made available in Ivy for backwards-compatibility with ViewEngine to make the transition to Ivy smoother. Since ViewEngine is deprecated and will soon be removed, those symbols are now deprecated as well.

IMPORTANT: this deprecation doesn't affect JIT mode in Ivy (JIT remains available with Ivy, however we are exploring a possibility of deprecating it in the future. See RFC: Exploration of use-cases for Angular JIT compilation mode).

TestRequest accepting ErrorEvent

Angular provides utilities for testing HttpClient. The TestRequest class from @angular/common/http/testing mocks HTTP request objects for use with HttpTestingController.

TestRequest provides an API for simulating an HTTP response with an error. In earlier versions of Angular, this API accepted objects of type ErrorEvent, which does not match the type of error event that browsers return natively. If you use ErrorEvent with TestRequest, you should switch to ProgressEvent.

Here is an example using a ProgressEvent:

const mockError = new ProgressEvent('error');
const mockRequest = httpTestingController.expectOne(..);

mockRequest.error(mockError);

Deprecated CLI APIs and Options

This section contains a complete list all of the currently deprecated CLI flags.

@angular-devkit/build-angular

API/Option May be removed in Details
deployUrl v15 Use baseHref option, APP_BASE_HREF DI token or a combination of both instead. For more information, see the deploy url.
Protractor builder v14 Deprecate as part of the Protractor deprecation.

Removed APIs

The following APIs have been removed starting with version 11.0.0*:

Package API Replacement Details
@angular/router preserveQueryParams queryParamsHandling

* To see APIs removed in version 10, check out this guide on the version 10 docs site.

Style Sanitization for [style] and [style.prop] bindings

Angular used to sanitize [style] and [style.prop] bindings to prevent malicious code from being inserted through javascript: expressions in CSS url() entries. However, most modern browsers no longer support the usage of these expressions, so sanitization was only maintained for the sake of IE 6 and 7. Given that Angular does not support either IE 6 or 7 and sanitization has a performance cost, we will no longer sanitize style bindings as of version 10 of Angular.

loadChildren string syntax in @angular/router

It is no longer possible to use the loadChildren string syntax to configure lazy routes. The string syntax has been replaced with dynamic import statements. The DeprecatedLoadChildren type was removed from @angular/router. Find more information about the replacement in the LoadChildrenCallback documentation.

The supporting classes NgModuleFactoryLoader, SystemJsNgModuleLoader, and SystemJsNgModuleLoaderConfig were removed from @angular/core, as well as SpyNgModuleFactoryLoader from @angular/router.

WrappedValue

The purpose of WrappedValue was to allow the same object instance to be treated as different for the purposes of change detection. It was commonly used with the async pipe in the case where the Observable produces the same instance of the value.

Given that this use case is relatively rare and special handling impacted application performance, the WrappedValue API has been removed in Angular 13.

If you rely on the behavior that the same object instance should cause change detection, you have two options:

Last reviewed on Wed May 03 2023

© 2010–2023 Google, Inc.
Licensed under the Creative Commons Attribution License 4.0.
https://angular.io/guide/deprecations