Skip to main content

What's new in Angular 17? The best new features of Angular 17

GGoogle team released the latest version of Angular – Angular 17 on November 6, 2023, creating a significant milestone for the front-end development.

Features and Updates:

1.     Angular 17 is the highly anticipated release for the community, bringing many new exciting features, updates, and improvements.

2.     New Syntax for Control Flow in Templates - new @if, @switch, @for, @case, @empty @end control flow syntax

3.     Deferred Loading - @defer partial template

4.     The Angular signals API

5.     Angular SSR and client hydration

6.     Automatic Migration to Build-in Control Flow

7.     Build Performance with ESBuild

8.     By default, set this newly generated component as a standalone, and now we don't have an app module file. To use (ng new angular17 --standalone=false) to get the app module file.

9.     Got a new brand logo

10.  Got a new dev documentation site

11.  ng update: update existing applications to Angular 17 using ng update command

12.  Super-Fast

Built-in control flow and the NgIf, NgSwitch and NgFor structural directives:

  1. The @if block replaces *ngIf for expressing conditional parts of the UI.
  2. The @switch block replaces ngSwitch with major benefits.
  3. The @for block replaces *ngFor for iteration, and has several differences compared to its structural directive NgFor predecessor.
  4. The track setting replaces NgFor's concept of a trackBy function.

New Syntax for Control Flow in Templates - new @if, @switch, @for, @case, @empty @end control flow syntax:

Let’s look at a one-by-one comparison with *ngIf:

Before Angular 17,

<div *ngIf="loggedIn; else guestUser">

  The user is logged in the application

</div>

<ng-template #guestUser>

  The user is not logged in the application

</ng-template>

With the built-in if statement, this condition will look like:

From Angular 17,

The @if block conditionally displays its content when its condition expression is true.

Let's see the example, here ‘a’ and ‘b’ are two of the variables that are used in the conditionals @if block.

@if (a > b) {

   {{a}} is greater than {{b}}

}

The @if block might have one or more associated @else blocks. Immediately after an @if block, you can optionally specify any number of @else if blocks and one @else block:

@if (a > b) {

  {{a}} is greater than {{b}

} @else if (b > a) {

  {{a}} is less than {{b}}

} @else {

  {{a}} is equal to {{b}}

}


The improved ergonomics is even more visible with *ngSwitch:

The new control flow enables significantly better type-narrowing in the individual branches in @switch, which is impossible in *ngSwitch.

Before Angular 17,

<div [ngSwitch]="accessLevel">

  <admin-dashboard *ngSwitchCase="admin"/>

  <moderator-dashboard *ngSwitchCase="moderator"/>

  <user-dashboard *ngSwitchDefault/>

</div>

Which with the built-in control flow turns into:

From Angular 17,

The syntax for @switch is very similar to @if statement. See what the basic looks like:

@switch (condition) {

  @case (caseA) {

    Case A.

  }

  @case (caseB) {

    Case B.

  }

  @default {

    Default case.

  }

}

The value of the conditional expression is compared to the case expression using the === operator.

The @switch does not have fall through, so you do not need an equivalent to a break or return statement.

The @default block is optional and can be omitted. If no @case matches the expression and there is no @default block, nothing is shown.

Built-in for loop - @for block - Repeaters

From Angular 17: The @for repeatedly renders the content of a block for each item in a collection. The collection can be represented as any JavaScript alterable but there are performance advantages of using a regular Array.

A basic @for loop looks like:

@for (item of items; track item.id) {

  {{ item.name }}

}

What Is ‘track’?

The track setting replaces NgFor's concept of a trackBy function.

The value of the ‘track’ expression determines a key used to associate array items with the views in the DOM. 

Inside @for contents, several implicit variables are always available:

1.      $count:         Number of items in a collection iterated over

2.      $index:         Index of the current row

3.      $first:            Whether the current row is the first row

4.      $last:             Whether the current row is the last row

5.      $even:          Whether the current row index is even

6.      $odd:            Whether the current row index is odd


These variables are always available with these names, but can be aliased via a let segment:

@for (item of items; track item.id; let idx = $index, e = $even) {

  Item #{{ idx }}: {{ item.name }}

}

@empty block

You can optionally include an @empty section immediately after the @for block content. The content of the @empty block displays when there are no items:

A basic @empty block looks like:

@for (item of items; track item.name) {

  <li> {{ item.name }} </li>

} @empty {

  <li> There are no items. </li>

}

Deferrable Loading: @defer partial template :

Now let’s talk about the future of lazy loading! The new deferrable views, allow you to lazily load the list of comments and all their transitive dependencies with a single line of declarative code:

@defer {

  <comment-list />

}

The most incredible part is that this all happens via a compile-time transformation: Angular abstracts all the complexity by finding components, directives, and pipes used inside of a @defer block, generating dynamic imports, and managing the process of loading and switching between states.

Angular makes using IntersectionObservers as simple as adding a deferrable view trigger!

@defer (on viewport) {

  <comment-list />

} @placeholder {

  <!-- A placeholder content to show until the comments load -->

  <img src="comments-placeholder.png">

}

Deferrable views offer a few more triggers:

1.     on idle — lazily load the block when the browser is not doing any heavy lifting

2.     on immediate — start lazily loading automatically, without blocking the browser

3.     on timer(<time>) — delay loading with a timer

4.     on viewport and on viewport(<ref>) — viewport also allows to specify a reference for an anchor element. When the anchor element is visible, Angular will lazily load the component and render it

5.     on interaction and on interaction(<ref>) — enables you to initiate lazy loading when the user interacts with a particular element

6.     on hover and on hover(<ref>) — triggers lazy loading when the user hovers an element

7.     when <expr> — enables you to specify your own condition via a Boolean expression


The Angular signals:

A signal is a wrapper around a value that can notify interested consumers when that value changes. Signals can contain any value, from simple primitives to complex data structures.

A signal's value is always read through a getter function, which allows Angular to track where the signal is used.

Signals may be either writable or read-only.

The angular signal () function creates a signal. This function takes two input parameters.

1. Initial value

2. Optional Equality function.

Whenever there is a change or update in signal value, it propagates the change to effect () such that you can run custom code inside the effect () function.

Using the equality function, you can write your own business logic to determine whether change should propagate to effect () or not.

Angular Signals multiple examples here... 


Angular SSR and client hydration (Revamped hybrid rendering experience):

Today, we bring server-side rendering (SSR) and static-site generation (SSG or prerendering) closer to developers with a prompt in ng new:

Alternatively, you can enable SSR in new projects with ng new myAppName --ssr

New @angular/ssr package:

To add hybrid rendering support to your existing application run:  ng add @angular/ssr

The above command

1)     will generate the server entry point

2)     To add SSR and SSG build capabilities

3)     To enable hydration by default

The @angular/ssr provides equivalent functionality to @nguniversal/express-engine which is currently in maintenance mode. If you’re using the express-engine, Angular CLI will automatically update your code to @angular/ssr.

 

New lifecycle hooks:

To improve the performance of Agular’s SSR and SSG, in the long term, we would like to move away from DOM emulation and direct DOM manipulations.

To enable this, we developed a set of new lifecycle hooks:

1)     afterRender — register a callback to be invoked each time the application finishes rendering

2)     afterNextRender — register a callback to be invoked the next time the application finishes rendering

Example of using afterRender and afterNextRender:

@Component({

  selector: 'my-chart',

  template: `<div #chart>{{ ... }}</div>`,

})

export class MyChart {

  @ViewChild('chart') chartRef: ElementRef;

  chart: MyChart|null;

 

  constructor() {

    afterNextRender(() => {

      this.chart = new MyChart(this.chartRef.nativeElement);

    }, {phase: AfterRenderPhase.Write});

  }

}

Build Performance with ESBuild: The new Application Builder

Angular has always had different builders to build our applications. There are two main types of Angular application:

client-side rendering: the entire application is built client-side. In other words, the application is represented in DOM (Document Object Model) format. Navigation, data fetching and templating are managed client-side instead of server-side.

server-side rendering: the application is rendered in HTML format, each page of the application is rendered in HTML format in response to navigation, and then this page is rehydrated to make it dynamic.

Depending on the type of application, the builder was different.

 

Angular used the builder:

1)     @angular-devkit/build-angular:browser to build a client-side rendering application

2)     @nguniversal/builders:ssr-dev-server to build a server-side rendering application.


Requesting to subscribe to my YouTube channel!  And explore the video content...


By Anil Singh | Rating of this article (*****)

Popular posts from this blog

nullinjectorerror no provider for httpclient angular 17

In Angular 17 where the standalone true option is set by default, the app.config.ts file is generated in src/app/ and provideHttpClient(). We can be added to the list of providers in app.config.ts Step 1:   To provide HttpClient in a standalone app we could do this in the app.config.ts file, app.config.ts: import { ApplicationConfig } from '@angular/core'; import { provideRouter } from '@angular/router'; import { routes } from './app.routes'; import { provideClientHydration } from '@angular/platform-browser'; //This (provideHttpClient) will help us to resolve the issue  import {provideHttpClient} from '@angular/common/http'; export const appConfig: ApplicationConfig = {   providers: [ provideRouter(routes),  provideClientHydration(), provideHttpClient ()      ] }; The appConfig const is used in the main.ts file, see the code, main.ts : import { bootstrapApplication } from '@angular/platform-browser'; import { appConfig } from ...

39 Best Object Oriented JavaScript Interview Questions and Answers

Most Popular 37 Key Questions for JavaScript Interviews. What is Object in JavaScript? What is the Prototype object in JavaScript and how it is used? What is "this"? What is its value? Explain why "self" is needed instead of "this". What is a Closure and why are they so useful to us? Explain how to write class methods vs. instance methods. Can you explain the difference between == and ===? Can you explain the difference between call and apply? Explain why Asynchronous code is important in JavaScript? Can you please tell me a story about JavaScript performance problems? Tell me your JavaScript Naming Convention? How do you define a class and its constructor? What is Hoisted in JavaScript? What is function overloadin...

List of Countries, Nationalities and their Code In Excel File

Download JSON file for this List - Click on JSON file    Countries List, Nationalities and Code Excel ID Country Country Code Nationality Person 1 UNITED KINGDOM GB British a Briton 2 ARGENTINA AR Argentinian an Argentinian 3 AUSTRALIA AU Australian an Australian 4 BAHAMAS BS Bahamian a Bahamian 5 BELGIUM BE Belgian a Belgian 6 BRAZIL BR Brazilian a Brazilian 7 CANADA CA Canadian a Canadian 8 CHINA CN Chinese a Chinese 9 COLOMBIA CO Colombian a Colombian 10 CUBA CU Cuban a Cuban 11 DOMINICAN REPUBLIC DO Dominican a Dominican 12 ECUADOR EC Ecuadorean an Ecuadorean 13 EL SALVA...

25 Best Vue.js 2 Interview Questions and Answers

What Is Vue.js? The Vue.js is a progressive JavaScript framework and used to building the interactive user interfaces and also it’s focused on the view layer only (front end). The Vue.js is easy to integrate with other libraries and others existing projects. Vue.js is very popular for Single Page Applications developments. The Vue.js is lighter, smaller in size and so faster. It also supports the MVVM ( Model-View-ViewModel ) pattern. The Vue.js is supporting to multiple Components and libraries like - ü   Tables and data grids ü   Notifications ü   Loader ü   Calendar ü   Display time, date and age ü   Progress Bar ü   Tooltip ü   Overlay ü   Icons ü   Menu ü   Charts ü   Map ü   Pdf viewer ü   And so on The Vue.js was developed by “ Evan You ”, an Ex Google software engineer. The latest version is Vue.js 2. The Vue.js 2 is very similar to Angular because Evan ...

55 Best TypeScript Interview Questions and Answers - JavaScript!

What Is TypeScript? By definition, "TypeScript is a typed superset of JavaScript that compiles to plain JavaScript." TypeScript is a superset of JavaScript which provides optional static typing, classes and interfaces. => The TypeScript was first made public in the year 2012. => Typescript is a modern age JavaScript development language. => TypeScript is a strongly typed, object oriented, compiled language. => TypeScript was designed by Anders Hejlsberg (designer of C#) at Microsoft. => TypeScript is both a language and a set of tools. As an Example of TypeScript, class Hello {     msg : string ;      constructor ( message : string ) {          this . msg = message ;      }       getMsg () {          return "Hello, " + this . msg ;      } } TypeScript introduced a great deal...