30 KiB
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, we deprecate APIs and features for a period of time before removing them. This gives you time to update your apps to the latest APIs and best practices.
This guide contains a summary of all Angular APIs and features that are currently deprecated.
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 apps, 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 APIs
This section contains a complete list all of the currently-deprecated APIs, with details to help you plan your migration to a replacement.
Tip: In the API reference section of this doc site, deprecated APIs are indicated by strikethrough. You can filter the API list by Status: deprecated.
{@a common}
@angular/common
API | Replacement | Deprecation announced | Notes |
---|---|---|---|
CurrencyPipe - DEFAULT_CURRENCY_CODE |
{provide: DEFAULT_CURRENCY_CODE, useValue: 'USD'} |
v9 | From v11 the default code will be extracted from the locale data given by LOCAL_ID , rather than USD . |
{@a core}
@angular/core
API | Replacement | Deprecation announced | Notes |
---|---|---|---|
CollectionChangeRecord |
IterableChangeRecord |
v4 | none |
DefaultIterableDiffer |
n/a | v4 | Not part of public API. |
ReflectiveInjector |
Injector.create |
v5 | See ReflectiveInjector |
ReflectiveKey |
none | v5 | none |
ViewEncapsulation.Native |
ViewEncapsulation.ShadowDom |
v6 | Use the native encapsulation mechanism of the renderer. See view.ts. |
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 |
ModuleWithProviders without a generic |
ModuleWithProviders with a generic |
v9 | See ModuleWithProviders section |
Undecorated base classes that use Angular features | Base classes with @Directive() decorator that use Angular features |
v9 | See undecorated base classes section |
{@a testing}
@angular/core/testing
API | Replacement | Deprecation announced | Notes |
---|---|---|---|
TestBed.get |
TestBed.inject |
v9 | Same behavior, but type safe. |
{@a forms}
@angular/forms
API | Replacement | Deprecation announced | Notes |
---|---|---|---|
ngModel with reactive forms |
See FormControlDirective usage notes | v6 | none |
{@a router}
@angular/router
API | Replacement | Deprecation announced | Notes |
---|---|---|---|
preserveQueryParams |
queryParamsHandling |
v4 | none |
{@a platform-webworker}
@angular/platform-webworker
API | Replacement | Deprecation announced | Notes |
---|---|---|---|
All entry points | none | v8 | See platform-webworker. |
{@a platform-webworker-dynamic}
@angular/platform-webworker-dynamic
API | Replacement | Deprecation announced | Notes |
---|---|---|---|
All entry points | none | v8 | See platform-webworker. |
{@a upgrade}
@angular/upgrade
API | Replacement | Deprecation announced | Notes |
---|---|---|---|
All entry points | @angular/upgrade/static |
v5 | See Upgrading from AngularJS. |
{@a upgrade-static}
@angular/upgrade/static
API | Replacement | Deprecation announced | Notes |
---|---|---|---|
getAngularLib |
getAngularJSGlobal |
v5 | See Upgrading from AngularJS. |
setAngularLib |
setAngularJSGlobal |
v5 | See Upgrading from AngularJS. |
{@a deprecated-features}
Deprecated features
This section lists all of the currently-deprecated features, which includes template syntax, configuration options, and any other deprecations not listed in the Deprecated APIs section above. It also includes deprecated API usage scenarios or API combinations, to augment the information above.
{@a wtf}
Web Tracing Framework integration
Angular previously has supported an integration with the Web Tracing Framework (WTF) for performance testing of Angular applications. This integration has not been maintained and 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.
{@a deep-component-style-selector}
/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 we deprecated support in Angular for all 3 of /deep/
, >>>
and ::ng-deep
. 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.
{@a template-tag}
<template> tag
The <template>
tag was deprecated in v4 to avoid colliding with the DOM's 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.
{@a ngmodel-reactive}
ngModel with reactive forms
Support for using the ngModel
input property and ngModelChange
event with reactive form directives was deprecated in version 6.
For more information, see the usage notes for FormControlDirective
and FormControlName
.
{@a reflectiveinjector}
ReflectiveInjector
In v5, Angular replaced the ReflectiveInjector
with the StaticInjector
. The injector no longer requires the Reflect polyfill, reducing application size for most developers.
Before:
ReflectiveInjector.resolveAndCreate(providers);
After:
Injector.create({providers});
{@a loadChildren}
loadChildren string syntax
When Angular first introduced lazy routes, there wasn't browser support for dynamically loading additional JavaScript. Angular created our 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
.
{@a activatedroute-props}
ActivatedRoute params and queryParams properties
ActivatedRoute contains two properties that are less capable than their replacements and may be deprecated in a future Angular version.
Property | Replacement |
---|---|
params |
paramMap |
queryParams |
queryParamMap |
For more information see the Router guide.
{@a reflect-metadata}
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 poylfill in most Angular applications unnecessary. Because the polyfill can be depended on by 3rd-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.
{@a static-query-resolution}
@ViewChild()
/ @ContentChild()
static resolution as the default
See the dedicated migration guide for static queries.
{@a contentchild-input-together}
@ContentChild()
/ @Input()
used together
The following pattern is deprecated:
@Input() @ContentChild(TemplateRef) tpl !: 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>;
{@a cant-assign-template-vars}
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 simply 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>
{@a undecorated-base-classes}
Undecorated base classes using Angular features
As of version 9, it's deprecated to have an undecorated base class that:
- uses Angular features
- is extended by a directive or component
Angular lifecycle hooks or any of the following Angular field decorators are considered Angular features:
@Input()
@Output()
@HostBinding()
@HostListener()
@ViewChild()
/@ViewChildren()
@ContentChild()
/@ContentChildren()
For example, the following case is deprecated because the base class uses @Input()
and does not have a class-level decorator:
class Base {
@Input()
foo: string;
}
@Directive(...)
class Dir extends Base {
ngOnChanges(): void {
// notified when bindings to [foo] are updated
}
}
In a future version of Angular, this code will start to throw an error.
To fix this example, add a selectorless @Directive()
decorator to the base class:
@Directive()
class Base {
@Input()
foo: string;
}
@Directive(...)
class Dir extends Base {
ngOnChanges(): void {
// notified when bindings to [foo] are updated
}
}
In version 9, the CLI has an automated migration that will update your code for you when ng update
is run.
See the dedicated migration guide for more information about the change and more examples.
{@a binding-to-innertext}
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.
{@a wtf-apis}
wtfStartTimeRange
and all wtf*
APIs
All of the wtf*
APIs are deprecated and will be removed in a future version.
{@a webworker-apps}
Running Angular applications in platform-webworker
The @angular/platform-*
packages enable Angular to be run in different contexts. For examples,
@angular/platform-server
enables Angular to be run on the server, and @angular/platform-browser
enables Angular to be run in a web browser.
@angular/platform-webworker
was introduced in Angular version 2 as an experiment in leveraging
Angular's rendering architecture to run an entire web application in a
web worker. We've learned a lot
from this experiment and have come to the conclusion that running the entire application in a web
worker is not the best strategy for most applications.
Going forward, we will focus our efforts related to web workers around their primary use case of offloading CPU-intensive, non-critical work needed for initial rendering (such as in-memory search and image processing). Learn more in the guide to Using Web Workers with the Angular CLI.
As of Angular version 8, all platform-webworker
APIs are deprecated.
This includes both packages: @angular/platform-webworker
and
@angular/platform-webworker-dynamic
.
{@a entryComponents}
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.
{@a moduleWithProviders}
ModuleWithProviders
type without a generic
Some Angular libraries, such as @angular/router
and @ngrx/store
, implement APIs that return a type called ModuleWithProviders
(typically via 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 }
]
};
}
}
{@a esm5-fesm5}
esm5
and fesm5
code formats in @angular/* npm packages
As of Angular v8, the CLI primarily consumes the fesm2015
variant of the code distributed via @angular/*
npm packages.
This renders the esm5
and fesm5
distributions obsolete and unnecessary, adding bloat to the package size and slowing down npm installations.
The future removal of this distribution will have no impact on CLI users, unless they modified their build configuration to explicitly consume these code distributions.
Any application still relying on the esm5
and fesm5
as the input to its build system will need to ensure that the build pipeline is capable of accepting JavaScript code conforming to ECMAScript 2015 (ES2015) language specification.
Note that this change doesn't make existing libraries distributed in this format incompatible with the Angular CLI. The CLI will fall back and consume libraries in less desirable formats if others are not available. However, we do recommend that libraries ship their code in ES2015 format in order to make builds faster and build output smaller.
In practical terms, the package.json
of all @angular
packages will change in the following way:
Before:
{
"name": "@angular/core",
"version": "9.0.0",
"main": "./bundles/core.umd.js",
"module": "./fesm5/core.js",
"es2015": "./fesm2015/core.js",
"esm5": "./esm5/core.js",
"esm2015": "./esm2015/core.js",
"fesm5": "./fesm5/core.js",
"fesm2015": "./fesm2015/core.js",
...
}
After:
{
"name": "@angular/core",
"version": "10.0.0",
"main": "./bundles/core.umd.js",
"module": "./fesm2015/core.js",
"es2015": "./fesm2015/core.js",
"esm2015": "./esm2015/core.js",
"fesm2015": "./fesm2015/core.js",
...
}
For more information about the npm package format, see the Angular Package Format spec.
{@a removed}
Removed APIs
The following APIs have been removed starting with version 9.0.0*:
Package | API | Replacement | Notes |
---|---|---|---|
@angular/core |
Renderer |
Renderer2 |
Migration guide |
@angular/core |
RootRenderer |
RendererFactory2 |
none |
@angular/core |
RenderComponentType |
RendererType2 |
none |
@angular/core |
WtfScopeFn |
none | v8 |
@angular/core |
wtfCreateScope |
none | v8 |
@angular/core |
wtfStartTimeRange |
none | v8 |
@angular/core |
wtfEndTimeRange |
none | v8 |
@angular/core |
wtfLeave |
none | v8 |
@angular/common |
DeprecatedI18NPipesModule |
CommonModule |
none |
@angular/common |
DeprecatedCurrencyPipe |
CurrencyPipe |
none |
@angular/common |
DeprecatedDatePipe |
DatePipe |
none |
@angular/common |
DeprecatedDecimalPipe |
DecimalPipe |
none |
@angular/common |
DeprecatedPercentPipe |
PercentPipe |
none |
@angular/forms |
NgFormSelectorWarning |
none | none |
@angular/forms |
ngForm element selector |
ng-form element selector |
none |
@angular/service-worker |
versionedFiles |
files |
In the service worker configuration file ngsw-config.json , replace versionedFiles with files . See Service Worker Configuration. |
*To see APIs removed in version 8, check out this guide on the version 8 docs site.
{@a http}
@angular/http
The entire @angular/http
package has been removed. Use @angular/common/http
instead.
The new API is a smaller, easier, and more powerful way to make HTTP requests in Angular.
The new API simplifies the default ergonomics: There is no need to map by invoking the .json()
method.
It also supports typed return values and interceptors.
To update your apps:
- Replace
HttpModule
withHttpClientModule
(from@angular/common/http
) in each of your modules. - Replace the
Http
service with theHttpClient
service. - Remove any
map(res => res.json())
calls. They are no longer needed.
For more information about using @angular/common/http
, see the HttpClient guide.
@angular/http |
Closest replacement in @angular/common/http |
---|---|
BaseRequestOptions |
HttpRequest |
BaseResponseOptions |
HttpResponse |
BrowserXhr |
|
Connection |
HttpBackend |
ConnectionBackend |
HttpBackend |
CookieXSRFStrategy |
HttpClientXsrfModule |
Headers |
HttpHeaders |
Http |
HttpClient |
HttpModule |
HttpClientModule |
Jsonp |
HttpClient |
JSONPBackend |
JsonpClientBackend |
JSONPConnection |
JsonpClientBackend |
JsonpModule |
HttpClientJsonpModule |
QueryEncoder |
HttpUrlEncodingCodec |
ReadyState |
HttpBackend |
Request |
HttpRequest |
RequestMethod |
HttpClient |
RequestOptions |
HttpRequest |
RequestOptionsArgs |
HttpRequest |
Response |
HttpResponse |
ResponseContentType |
HttpClient |
ResponseOptions |
HttpResponse |
ResponseOptionsArgs |
HttpResponse |
ResponseType |
HttpClient |
URLSearchParams |
HttpParams |
XHRBackend |
HttpXhrBackend |
XHRConnection |
HttpXhrBackend |
XSRFStrategy |
HttpClientXsrfModule |
@angular/http/testing |
Closest replacement in @angular/common/http/testing |
---|---|
MockBackend |
HttpTestingController |
MockConnection |
HttpTestingController |