Angular, a web applications framework based on typescript, is one of the best and most glossy creations of Google. Angular released its latest version, Angular 14, on June 2, 2022. Here we are going to talk about the updates that the Angular 14 release has brought for us.
Let’s talk about the features and improvements in Angular’s latest version without any further delay.
Table of Contents
What’s new in Angular 14?
The major changes that came up with the Angular new version are
- Typed Reactive Forms
- Standalone Components
- Enhanced / Extended Diagnostics
- Page Title Accessibility
- Angular CLI Auto-completion
- Binding of Protected Components Members
And many more that we will go through in this Angular new version (Angular 14) article.
Typed Reactive Forms
In Angular v14, reactive forms are strongly typed forms by default. That means in Angular 14 if we define a reactive form control, group, and form array the form value will follow the defined type at the time of initialization or the initial value.
With the reactive form, you can explicitly define a form model. Let’s start with a basic user registration form:
const userForm = new FormGroup({ email: new FormControl(''), // will accept string|null password: new FormControl(''), // will accept string|null phone: new FormControl(''), // will accept string|null age?: new FormControl(1) // optional & accept number|null });
Angular v14 and previous angular 2+ versions provide many functions that can be used to interact with reactive forms e.g. userForm.value, userForm.patchValue, and many more. In previous Angular versions when we use these types of functions it adds type any somewhere in code execution or interaction and makes the FormControl, FormGroup, or FormArray a non-strict typed form. For example, we can write invalid code with successful compilation.
const countryCode = userForm.value.phone.countryCode; // Angular v2 to Angular v13 // Angular v14 Compile Successfully Compile Error
But Angular v14 will give a compile error for the above line of code because there isn’t any countryCode attribute in the phone control value and the form is strictly typed form.
Automated Untyped Forms Migration:
When upgrading to Angular latest version (Angular 14), an automated migration will run and replace all forms classes with corresponding untyped versions.
For example the following code snippet:
const userForm = new FormGroup({ email: new FormControl(''), // will accept string|null password: new FormControl(''), // will accept string|null phone: new FormControl(''), // will accept string|null age?: new FormControl(1) // optional & accept number|null });
will be replaced with
// Angular v14 untyped form by running ‘ng update’ const userForm = new UntypedFormGroup({ email: new UntypedFormControl(''), password: new UntypedFormControl(''), phone: new UntypedFormControl(''), age: new UntypedFormControl(1) }); // Types type UntypedFormControl = FormControl<any>; type UntypedFormGroup = FormGroup<any>; type UntypedFormArray = FormArray<any>;
In the above registration form for Angular 14, there is? with the age attribute that defines it is optional and can be added and removed dynamically.
Full example code snippet for strictly typed form
// Define interface for Registration Form Interface RegisterForm { email: FormControl<string>, password: FormControl<string>, phone: FormControl<string>, age?: FormControl<number|null> }; const userForm = new FormGroup<RegistrationForm>({ email: new FormControl('', {nonNullable: true}) password: new FormControl('', {nonNullable: true}), phone: new FormControl('', {nonNullable: true}), age?: new FormControl(null) });
Some of the valid and invalid statements for the above code snippet
// Valid statements userForm.removeControl(‘age’) userForm.addControl(‘age’) userForm.patchValue(‘age’, 22) userForm.patchValue(‘age’, null) userForm.patchValue(‘email’, ‘example@example.com’) // Invalid statements userForm.removeControl(‘phone’) userForm.patchValue(‘phone’, null) // nonNullable is true userForm.patchValue(‘phone’, 123) // only accept string values
This feature is specially added in Angular 14 on public requests. It is only available for the Angular Reactive Forms (not for template-driven forms) with complete backward compatibility.
Standalone Components
Standalone components, directives, and pipes will make the Angular development process easier and smooth without worrying about declaring any component in the corresponding NgModule before importing it anywhere in the application. Standalone components are basically introduced to make Angular a component-based framework like React or any other component-based library or framework.
Creating Standalone Components
In previous angular versions if you try to import a component without declaring it in the NgModule the angular compiler reports an error. in Angular 14, to create a standalone component, directive, or pipe via angular CLI you can use the following command that is available with Angular v14 cli
ng generate <component|directive|pipe> <name> --standalone
Which will add a standalone flag “standalone: true” in the component, directive, or pipe and you can use it without declaring it in NgModule In Standalone components if there are any dependencies, you can directly import them into your components instead of d. For example, if ImageComponent is a standalone component, it can directly import UploadMediaComponent: in Angular 14
@Component({ standalone: true, selector: 'image-view', imports: [UploadMediaComponent], template: ` ... <upload-media></upload-media> .... `, }) export class ImageComponent { // component logic }
Imports attributes can also be used for standalone directives and pipes. In this way, standalone components can be defined without declaration in NgModule for template dependencies in this angular new version (Angular 14).
Existing NgModules Libraries in Standalone Component
If you want to use your existing NgModules in the newly created standalone component in Angular 14 you can directly import a module in your standalone component to use MatProgressBarModule in a standalone component we import it like
// Angular v14: existing NgModule MatProgressBar library @Component({ standalone: true, selector: ‘upload-media’, imports: [MatProgressBarModule], template: `... <div class=”uploading” progress-bar></progress-bar> ....`, }) export class UploadMediaComponent { // component logic }
You can use standalone components with already developed NgModule-based libraries, packages, and dependencies in your template. So, you do not need to worry about the already existing Angular libraries ecosystem.
Standalone Components in NgModule-based Applications
Standalone components, directives, and pipes can also be used by importing them into existing NgModule-based applications. You can import a standalone component directive or pipe as before using the NgModule imports attribute
// Angular v14 standalone component in NgModule based apps @NgModule({ declarations: [GalleryComponent], exports: [GalleryComponent], imports: [ImageComponent], }) export class GalleryModule {}
Routing and Lazy Loading
Angular 14 router APIs are updated for standalone components to support lazy loading scenarios without NgModule requirements.
Lazy Loading Standalone Components
In Angular 14 by using loadComponent you can easily lazily load a standalone component route and by using loadChildren you can lazily load many routes at once:
// Angular v14 Single standalone component Route export const ROUTES: Route[] = [ {path: 'gallery', loadComponent: () => import('./gallery/gallery.component').then(components => components.GalleryComponent)}, ]; // Angular v14 Many Routes at once // In the main application: export const ROUTES: Route[] = [ {path: 'gallery', loadChildren: () => import('./gallery/routes').then(components => components.GALLERY_ROUTES)}, // ... ]; // In gallery/routes.ts: export const GALLERY_ROUTES: Route[] = [ {path: '', component: GalleryComponent}, {path: 'gallery/add-image', component: UploadImageComponent}, {path: 'gallery/image/<:id>', component: ImageViewComponent}, // ... ];
This will only work if and only if the component is standalone.
Note
The standalone component feature is in developer preview and ready for developers to try but is not stable.
Looking to Hire Angular Development Team?
Share the details of your request and we will provide you with a full-cycle team under one roof.
Enhanced / Extended Diagnostics
Angular v14 enhanced/extended diagnostics are added to provide more informative insights in the templates that you can review to improve your code. Enhanced diagnostic in Angular 14 gives warnings on compile-time with proper actionable suggestions for the templates before run-time.
Currently, Angular v14 supports the following enhanced diagnostics:
- invalidBananaInBox
- nullishCoalescingNotNullable
“Banana in a Box” Error (invalidBananaInBox)
A very common syntax blunder made by developers often is to flip the brackets and parentheses in two0way binding writing wrong syntax ([]) instead of [()]. As () looks like a banana and [] looks like a box that’s why it was named as “Banan in a Box” error because a box can’t be put into a banana but yes banana can be kept into a box.
Angular v14 cli acknowledges these as detailed warnings with guidance on how you can fix this warning in the editor while developing your code.
Catch Nullish Coalescing on Non-nullable values (nullishCoalescingNotNullable)
Angular v14 enhanced diagnostics also display a warning for nullish coalescing operators (??) in Angular latest version (Angular v14) templates where input cannot be nullable which means its type does not have null or undefined.
Configurations
Enhanced / Extended diagnostics are also configurable in tsconfig.ts depending on your need if you want to consider such diagnostics as waning, error, or suppression.
// Angular v14, extended diagnostics configurations { "angularCompilerOptions": { "extendedDiagnostics": { // The categories to use for specific diagnostics. "checks": { // Maps check name to its category. "invalidBananaInBox": "suppress" }, // The category to use for any diagnostics not listed in `checks` above. "defaultCategory": "error" } } }
More Improvements In Angular 14
The angular latest version (Angular v14) supports the latest typescript version 4.7 and sets ES2020 as the default target.
Moreover, there are more features that should be highlighted in Angular 14.
Optional injectors in Embedded Views
Angular v14 adds support passing an optional injector while developing an embedded view through ViewContainerRef.createEmbeddedView and TemplateRef.createEmbeddedView. This can be useful where you want to have specific dependency behavior within a specific template.
// Angular embedded views injectors viewContainer.createEmbeddedView(templateRef, context, { injector: injector, })
Binding of Protected Components Members
In Angular 14, you can now bind protected component members directly in the templates that were not possible before that. You won’t be able to have control over the public API surface of your reusable components before Angular 14.
NgModel OnPush
Angular 14 enhances its change detection strategy which reflects the changes OnPush in the UI templates.
// Angular v14, OnPush change detection strategy @Component({ selector: 'app-root', template: ` <child-component [ngModel]="value"></child-component> `, changeDetection: ChangeDetectionStrategy.OnPush }) export class ExampleComponent {}
Streamlined Page Title Accessibility
Each page of the application should have a unique, readable, and understandable title so the browser can identify it and save it in browser history. Angular v14 Router has a property “title” for every Route that can be used for this purpose which requires no additional imports and is strictly typed.
// Angular v14, page title const routes: Routes = [{ path: 'dashboard', component: DashboardComponent title: 'My App - Dashboard' // <-- Page title }, { path: 'contact-us', component: ContactUsComponent, title: 'My App - Contact Us' // <-- Page title }];
You can also add a custom title by using TitleStrategy.
// Angular v14, page title with TitleStrategy const routes: Routes = [{ path: 'dashboard', component: DashboardComponent }, { path: 'contact-is', component: ContactUsComponent, title: 'Contact Us' // <-- Page title }]; @Injectable() export class PageTitleStrategy extends TitleStrategy { override updateTitle(routerState: RouterStateSnapshot) { const title = this.buildTitle(routerState); if (title !== undefined) { document.title = `My App - ${title}`; } else { document.title = `My App - Dashboard`; }; }; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule], providers: [ {provide: TitleStrategy, useClass: PageTitleStrategy}, ] }) export class AppRoutingModule { }
If a user navigates to /contact-us, it will show a page title “My App – Contact Us” and for the routes like /dashboard which don’t have any “title” attribute it will show “My App – Dashboard”.
Angular CLI Auto-Completion
If you love to use angular CLI to generate modules, components, directives, and pipes that enhance the productivity, in previous versions, you will feel like you have to go through the official docs to check the command syntax in most of the cases or you have to run ng –help to get available options.
ng completion
with the arrival of Angular new version (Angular 14), this is not necessary to go to the docs to check the command syntax. Angular 14 provides a new feature in the cli to provide real-time type ahead auto-completion to enhance productivity.
Automated Setup
The Angular v14 CLI will prompt and ask to set up auto-completion for the first time. Simply type “Yes” and CLI will automatically take care of the rest.
Manual Setup
The first time you must have run ng completion to enable the auto-completion.
After tying ng you just need to press <Tab> it will show you all available options. For example, the
ng serve was a common type many people type it as ng server or ng sevre. Now with the help of type ahead auto-completion with Angular v14 CLI, it will highlight the complete word without complete word typing.
ng cache
Angular v14 or previous versions save a number of cache on disk by default which helps to reduce the build time for applications and libraries to test applications if it is run several times as it uses the cache information after the first release.
You can enable, disable, clean the cache and also check the statistics of the saved cache information (ng cache info).
Removed Camel Case Arguments/Flags
In Angular v14, the camel case arguments in the CLI are removed. Now all of the arguments can be used in –lower-skewer-case format.
Angular v14 Devtools offline Availability in Firefox
In Angular 14, Firefox’s angular dev tools extension is not available offline and can be used without internet availability.
Conclusion
So, with the above features of Angular 14 (Angular new version), you must be looking forward to applying these in your future development process. We have to stop here unless Google releases a new version with more exciting features that can enhance the development process and make it more productive.