Latest Angular features - 2021

In this story, we will peek at some of additions in recent angular versions. We will look into AOT, Service workers, Angular libraries, Angular elements and other features. We will start with Angular (4/5+) features and then look into Angular (6–12) features.

NoValidate added to form elements with FormsModule (4+)

Angular adds novalidate attribute to form elements when FormsModule is included. This disables browser’s native form validation, it is useful as often custom validation is defined in Angular. To re-enable native forms behaviors, use ngNoForm or add ngNativeValidate

Support of else statement with ngIf directive (4+)

The else template is used to display a template when the expression has false value. The else binding points to a <ng-template> labeled #otherContent in below example and if show is false other text is displayed.

<div *ngIf="show; else otherContent">Text to show</div>

<ng-template #otherContent>Other text</ng-template>

Support for email validator in <input> (4+)

Instead of writing pattern to validate email in input fields, there is email validator in angular, just add email or email = "true" in element.

<input type="email" name="email" ngModel email>

AOT Compilation by default in angular production builds (5+)

Angular offers two ways to compile your application:

  1. Just-in-Time (JIT): compiles app in the browser at runtime — default with ng-build or ng-serve
  2. Ahead-of-Time (AOT): compiles app at build time — append --aot flags to ng-build or ng-serve cli commands

By compiling doesn’t imply it is converting JavaScript to binary but it is compiling to JavaScript that can be directly executed in browser, e.g. components and templates are converted to executable JavaScript

The AOT compiling provides several benefits like faster rendering, fewer async requests (through inline html/css templates), smaller size, detect template errors earlier and better security.

With Angular (5+), the production builds (e.g. ng build --prod) are AOT compiled by default.

Service Workers (5+)

Angular now provides rich support for Progressive Web Apps (PWA) by configuring service workers using @angular/service-worker package. Adding service workers is as easy as executing below command:

ng add @angular/pwa

It adds @angular/service-worker package, register it in app module, include link to manifest.json in index.html file, add icon files and service worker configuration file called ngsw-config.json which has settings like caching behaviour. It enables service worker when project is built with production flag.

New Life Cycle events (5+): GuardsCheckStart and ChildActivationStart

New life cycle events are added to the router. These events can be used for showing spinner on a specific router outlet or to measure performance of guards and/or resolvers. The routing life cycle events fire in the following sequence:

GuardsCheckStart -> ChildActivationStart -> ActivationStart ->
GuardsCheckEnd -> ResolveStart -> ResolveEnd -> ActivationEnd ->
ChildActivationEnd

Here is sample example:

class SampleComponent {
constructor(public router: Router, spinner: Spinner) {
router.events.subscribe(e => {
if (e instanceof ChildActivationStart) {
spinner.start(e.route);
} else if (e instanceof ChildActivationEnd) {
spinner.end(e.route);
}
});
}
}

Singleton Services (6+) using providedIn

The new preferred way to create a singleton services is to specify on the service that it should be provided in the application root. This is done by setting providedIn to root on the service's @Injectable decorator. It’s also possible to specify that a service should be provided in a particular @NgModule

import { Injectable } from '@angular/core';@Injectable({
providedIn: 'root',
})
export class WeatherService {
}

The services will be bundled only in modules where they are injected, thus enabling tree shaking.

Angular Libraries (6+)

The angular now makes it easy to generate and consume angular library.

There are 3 important steps:

  1. Generate Library
ng g library sampleLib

2. Build Lib (for production use --prod flag)

ng build sampleLib

3. Consume library

The library can be consumed by importing and declaring in app module:

Import:

import { SampleLibComponent } from 'sampleLib';

Add in declaration:

declarations: [SampleLibComponent]

Use like any other component:

<lib-sampleLib></lib-sampleLib>

The lib is prefix is added by default, can be changed using -- prefix flag while generating library.

Note that the library is imported as if it was present in node_modules . Angular CLI first looks in your tsconfig paths, then in the node_modules folder, so same code can be used if library is published. Below is added in tsconfig.json by CLI when library is generated:

"paths": {
"sampleLib": ["dist/sample-lib"],
"sampleLib/*": ["dist/sample-lib/*"]
}

Custom Elements (6+)

Elements are Angular components packaged as custom elements, a web standard for defining new HTML elements in a framework-agnostic way. The custom element extends HTML by allowing you to define a tag whose content is created and controlled by JavaScript code. Creating a custom element is simple and straightforward, and automatically connects component-defined view with change detection and data binding, mapping Angular functionality to the corresponding native HTML equivalents.

Angular provides the createCustomElement() function for this from @angular/elements . First create new project as usual, but note that custom prefix is required for custom elements:

ng new elementdemo --prefix custom

Then add @angular/elements using ng add :

ng add @angular/elements

Add component (e.g.ng g c popupElement ) just like regular component and it can be used in index.html (outside of angular) like other html elements:

e.g. <popup-element message="Hello"></popup-element>

Also, define custom element in App Module:

export class AppModule {
constructor(private injector: Injector) {
customElements.define(
'popup-element',
createCustomElement(PopupElementComponent, { injector: this.injector })
);
}
ngDoBootstrap() {}
}

and add the component in declarations and entryComponents of @NgModule in app module:

declarations: [AppComponent, PopupElementComponent],
entryComponents: [PopupElementComponent]

That’s all need to be done. This works in all major browsers (except for latest chrome, for that change "target": "es5" to "target": "es2015" in tsconfig.json and add es2015 polyfill for browsers not supporting es2015).

Bundle Budgets (7+)

New projects are also now defaulted using Size Budget . The build system notifies when app is reaching size limits. Default is warnings at 2MB and errors at 5MB.

The budget is set in angular.json under project > [ProjectName] > architect > build > configurations >production. This feature is more of keeping check on app bundle size within team — to get it fixed as soon as it hits the budget.

"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
}
]

Note: To get Warning or error for budget, you need to run build for production. The type specifies which scripts to check for limit e.g. all, allScript, any, anyScript, bundle, initial.

ng build --prod

Differential Loading (8 +)

Differential loading is a process by which the browser chooses between modern or legacy JavaScript based on its own capabilities.

Part of Sample output below from the index.html file produced during a build using ng build. Each script tag has a type="module" or nomodule attribute. Browsers with native support for ES modules only load the scripts with the module type attribute and ignore scripts with the nomodule attribute. Legacy browsers only load the scripts with the nomodule attribute, and ignore the script tags with the module type that load ES modules. The modern bundle contains modern syntax, takes advantage of built-in support in modern browsers, ships less polyfills, and results in a smaller bundle size. The second bundle, includes the additional compiled code, all necessary polyfills, and results in a larger bundle size. This strategy allows you to continue to build your web application to support multiple browsers, but only load the necessary code that the browser needs

<script src="main-es2015.js" type="module"></script>
<script src="main-es5.js" nomodule></script>

The modern bundle contains modern syntax, takes advantage of built-in support in modern browsers, ships less polyfills, and results in a smaller bundle size. The second bundle, includes the additional compiled code, all necessary polyfills, and results in a larger bundle size. This strategy allows you to continue to build your web application to support multiple browsers, but only load the necessary code that the browser needs

Lazy Module Generator (8.1+)

The module schematics can now take a --route option to indicate that you want to generate a lazy-loaded module.

Example: Below command generates AboutModule in its own directory, also automatically adds route about to lazy load module in app module — the already existing module name provided with module argument.

ng g module about --route about --module app

Run Specific tests (8.1+)

Introduce in Angular cli 8.1, it is now possible to run specific test suite by providing files with include argument.

Example - Run all test from app/about folder:

ng test --include app/about/*.spec.ts

Example - Run todoAPIservice.spec.ts:

ng test --include app/services/todoAPIservice.spec.ts

Ivy Compiler (9+)

Version 9 moves all applications to use the Ivy compiler and runtime by default.

Type Safety: The new Ivy compiler is faster and offers stronger type safety. Two type checking flags are added in addition to the default:

1. fullTemplateTypeCheck- checks everything within your template (ngIf, ngFor, ng-template, etc)

2. strictTemplates - Applies the strictest Type System rules for type checking.

Smaller Bundle Size: The Ivy compiler generates small bundles by tree-shaking and generate less code for Angular components.

AOT: The AOT is default even for Dev mode builds. This means compile time checking is same as production builds. Also, compilation performance is improved.

Faster Tests: In Ivy, TestBed doesn’t recompile components between tests unless a component has been manually overridden so test runs faster.

Faster Internationalization(i18n): Build-time i18n substitutions are moved to later stage in the build process.

Debugging: There are improvement in debugging applications - Error messages are more readable, more useful stack trace, the new ng object for debugging is available which provide methods like applyChange.

Automatic Inlining of Fonts (11+)

To Speed up first contentful paint, Angular CLI will download and inline fonts that are being used and linked in the application. No code changes required to enable this feature

Improved Reporting and Logging (11+)

There are new CLI output updates to make logs and reports easier to read.

Inline SASS (12+)

  • SASS can be specified inline in the styles field of the @component decorator.

Strict Mode and Production Build (12+)

  • Running ng build defaults to production.
  • Strict mode is enabled by default in the CLI. It helps in catching more errors. It enables strictmode in TypeScript, as well as other strictness flags recommended by the TypeScript team. Specifically, forceConsistentCasingInFileNames, noImplicitReturns, noFallthroughCasesInSwitch. It turns on strict Angular compiler flags strictTemplates, strictInjectionParameters and strictInputAccessModifiers . It also reduces bundle size budget defaults.
  • Webpack 5 support is added.

Thanks for reading.

--

--

--

Full stack .Net developer, Web developer and Web Surfer.

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Node js worker threads for multithreading (typescript)

JavaScript String

Implement JavaScript’s new operator yourself — A killer Frontend interview question

JS Horror Story: Learning VueJS Episode #2

How to Start your Coding Journey?

JavaScript: The Spread Operator

5 Ways To Loop Over DOM Elements With QuerySelectorAll in JavaScript

Things to know for a JavaScript developer in 2020

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Chirag Rupani

Chirag Rupani

Full stack .Net developer, Web developer and Web Surfer.

More from Medium

Analyzing Angular micro-frontends with Sonarcloud

Lazy Loading in Angular

Using Charts in Angular

How to Test Chart.js in an Angular Component