G Google team released the latest version of Angular – Angular 17 on November 6, 2023, creating a significant milestone for the super fast front-end development.
What Are the New Features in Angular 17?
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
What is the new Built-in control flow?
Built-in control flow and the NgIf, NgSwitch and NgFor structural directives:
- The @if block replaces *ngIf for expressing conditional parts of the UI.
- The @switch block replaces ngSwitch with major benefits.
- The @for block replaces *ngFor for iteration, and has several differences compared to its structural directive NgFor predecessor.
- The track setting replaces NgFor's concept of a trackBy function.
What Are The 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,
What Is the new control flow @if block?
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}}
}
What Is the new control flow @switch?
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.
What Is The @default Block?
The @default block is optional and can be omitted. If no @case matches the expression and there is no @default block, nothing is shown.
What Is Built-in for loop -
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 }}
}
What Is @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>
}
What Is Deferrable Loading? What is @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">
}
What Are Deferrable Views Triggers?
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
What Are 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...
What Is the Angular SSR and Client Hydration?
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 --ssrNew @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.
What Are the New Lifecycle Hooks in Angular 17?
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});
}
}
What Are The New Application Builders to Build Performance with ESBuild?
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.
What Builder is used in Angular 17?
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...