Showing posts with label Angular 14 New Features | RAJESH GAMI. Show all posts
Showing posts with label Angular 14 New Features | RAJESH GAMI. Show all posts

Angular 14 New Features | RAJESH GAMI

 

How do I install Angular 14?

Angular 14 can be installed via npm with the following flags:

Open a new command line interface and run the following command to install the latest version of Angular.

npm install --global @angular/cli@next

This will globally install the latest version of the Angular CLI on your development machine.

Check the Angular CLI version with the following command:

ng version

Angular 14 Features
 

1. Standalone Component 

With the release of Angular14, the standalone component will eventually become a viable option, eliminating the need for Angular modules.

Standalone components are not declared in existing NgModules and can directly manage their own dependencies (rather than letting them manage them) and make them directly dependent on them without the need for an intermediate NgModule.

Key Points

  • The standalone component have the flag "standaloneand the value must be set to "true"
  • No need to add standalone components to ngModule.
  • You can import the required modules into the component itself.
  • Command,
    ng g c standalonedemo --standalone
    JavaScript
    import { Component, OnInit } from '@angular/core';
    import { CommonModule } from '@angular/common';
    
    @Component({
        selector: 'app-standalonedemo',
        standalone: true,
        imports: [CommonModule],
        templateUrl: './standalonedemo.component.html',
        styleUrls: ['./standalonedemo.component.css']
    })
    export class StandalonedemoComponent implements OnInit {
        constructor() {}
        ngOnInit(): void {}
    }
    JavaScript
    <div class="container pages text-justify pb-5">
        <h1 class="mb-4">Angular 14 Standalone Component</h1>
        <p>standalonedemo works!</p>
    </div>
    Markup

2. The Typed Forms

The most common requirement for Angular features on GitHub is for strongly typed forms. This enhances the framework's model-driven approach to the form processing process.

Important Points

  • This feature is for reactive forms only.
  • To use this feature, tsconig.js must be in strict mode
  • Typed forms ensure that the values ​​in form controls, groups, and arrays are type-safe across API surfaces.
  • This helps developers generate secure forms and complex nested objects.
  • If you use an older version, you can use the untyped version.

Example: Create the component of a standalone contact, add four fields (name, number, email, message) and import the ReactiveForms Module as shown below.

import { CommonModule } from '@angular/common';
import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup, ReactiveFormsModule, UntypedFormControl, UntypedFormGroup } from '@angular/forms';

@Component({
    selector: 'app-contactus',
    standalone: true,
    imports: [CommonModule, ReactiveFormsModule],
    templateUrl: './contactus.component.html',
    styleUrls: ['./contactus.component.css']
})
export class ContactusComponent implements OnInit {
    constructor() {}
    ngOnInit(): void {}
    contactForm = new FormGroup({
        name: new FormControl < string > (''),
        email: new FormControl(''),
        message: new FormControl(''),
        number: new FormControl()
    });
    contactFormUntyped = new UntypedFormGroup({
        name: new UntypedFormControl(''),
        email: new FormControl(''),
        message: new FormControl(''),
        number: new FormControl()
    });
    Submit() {
        console.log(this.contactForm.value);
        console.log(this.contactForm.value.email?.length); //check the null value
        console.log(this.contactForm.value.email!.length); //If you are sure value is not null
        console.log(this.contactFormUntyped.value.name.length); // throw error in browser
    }
}
JavaScript
<div class="container pages text-justify pb-5">
    <h1 class="mb-4">Angular 14  Typed Form</h1>
    <section class="mb-4">
        <!--Section heading-->
        <div class="row">
            <!--Grid column-->
            <div class="col-md-9 mb-md-0 mb-5">
                <form [formGroup]="contactForm" (ngSubmit)="Submit()">
                    <!--Grid row-->
                    <div class="row">
                        <!--Grid column-->
                        <div class="col-md-6">
                            <div class="md-form mb-0">
                                <input formControlName="name" type="text" class="form-control">
                                <label for="name" class="">Your name</label>
                            </div>
                        </div>
                        <!--Grid column-->
                        <!--Grid column-->
                        <div class="col-md-6">
                            <div class="md-form mb-0">
                                <input formControlName="email" type="text" class="form-control">
                                <label for="email" class="">Your email</label>
                            </div>
                        </div>
                        <!--Grid column-->
                    </div>
                    <!--Grid row-->
                    <!--Grid row-->
                    <div class="row">
                        <div class="col-md-12">
                            <div class="md-form mb-0">
                                <input formControlName="number" type="text" class="form-control">
                                <label for="subject" class="">Number</label>
                            </div>
                        </div>
                    </div>
                    <!--Grid row-->
                    <!--Grid row-->
                    <div class="row">
                        <!--Grid column-->
                        <div class="col-md-12">
                            <div class="md-form">
                                <textarea formControlName="message" type="text" rows="2" class="form-control md-textarea"></textarea>
                                <label for="message">Your message</label>
                            </div>
                        </div>
                    </div>
                    <!--Grid row-->
                    <button type="submit" class="btn btn-primary">Submit</button>
                </form>
            </div>
            <!--Grid column-->
        </div>
    </section>
</div>
Markup

3. Optimized accessibility for page titles (title strategy)

When developing an application, page titles reflect the content of the page differently. In Angular 13, the entire process of adding titles has been streamlined with a new route. The title property of Angular router. However, Angular 14 does not require any additional imports when adding titles to a page.

Go to the routing module. Now define the route. By extending the app routing module as shown, there is a function to add a title to the route and implement TitleStrategy.

import { NgModule } from '@angular/core';
import { RouterModule, RouterStateSnapshot, Routes, TitleStrategy } from '@angular/router';
import { ContactusComponent } from './contactus/contactus.component';
import { HomeComponent } from './home/home.component';
import { StandalonedemoComponent } from './standalonedemo/standalonedemo.component';

const routes: Routes = [
  {path:'',component:HomeComponent, title : "Core Knowledge Sharing"},
  { path: 'standalonedemo', component: StandalonedemoComponent, title : "Stand alone Component" },
  { path: 'contactus', component: ContactusComponent, title : "Contact Us" }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule extends TitleStrategy {
  updateTitle(snapshot: RouterStateSnapshot): void {
     const pageTitle = this.buildTitle(snapshot);
     if(pageTitle != undefined){
      document.title = "${pageTitle}"
     }
  }
}
JavaScript

4. Advanced Developer Diagnostics  (ng compilation) 

This feature of Angular v14 provides an extensible framework that supports better insights into templates and provides suggestions for potential improvements. .. It also checks for syntax errors in components like the Contacts component and removes Reactive.

For example, type the wrong command, such as ngserve, and then get the correct command suggestions.

5. Bind to a protected component member  

 In v14, thanks to the contribution, you can now bind to component members that are protected directly from the template. Zack Elliott!

@Component({
    selector: 'my-component',
    template: '{{ message }}',  // Now compiles!
})
export class MyComponent {
    protected message: string = 'Hello world';
}
JavaScript

6. Optional Injectors in Embedded Views

v14 adds support for passing optional injectors when creating embedded views via ViewContainerRef.createEmbeddedView and TemplateRef.createEmbeddedView Injectors allow you to customize the behavior of dependency injection within a particular template.

This allows for a cleaner API for creating reusable components and component primitives for Angular CDK.
viewContainer.createEmbeddedView(templateRef, context, {
  injector: injector,
})
JavaScript

7. NgModel OnPush

And finally, a community post by Artur Androsovych closes the most important issue, allowing NgModel changes to be reflected in the OnPush component's UI. There are two components. The first is a simple child component with some inputs and basic [ngModel] directive support via the ControlValueAccesor interface. The second is the parent component, which has an onPush change detection strategy and inserts a value into the child component via the [ngModel] directive (immediately after it is marked for change via the ChangeDetectorRef class). When the ngModel is updated, the child component still shows the old value in the template, but the component object shows the actual value in the target property.

import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core';

@Component({
    selector: 'app-onpushdemo',
    template: `<div>
  <app-child [ngModel]="value"></app-child>
</div>`,
    styleUrls: ['./onpushdemo.component.css'],
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class OnpushdemoComponent implements OnInit {
    public value: any = "old value";
    constructor(private _changeDetector: ChangeDetectorRef) {
        setTimeout(() => {
            debugger;
            this.value = "new value";
            this._changeDetector.markForCheck();
        }, 5000)
    }
    ngOnInit(): void {}
}
JavaScript
import { Component, forwardRef, OnInit } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';

@Component({
    selector: 'app-child',
    template: `<div (click)="click()">Current Value: {{value}}.
  Click me to force change detection</div>`,
    styleUrls: ['./child.component.css'],
    inputs: ['value'],
    providers: [{
        provide: NG_VALUE_ACCESSOR,
        useExisting: forwardRef(() => ChildComponent),
        multi: true
    }],
})
export class ChildComponent implements OnInit {
    constructor() {}
    public value: any;
    public onChange: (_: any) => void = (_: any) => {
        // do nothing
    };
    public onTouched: () => void = () => {
        // do nothing
    };
    public writeValue(value: any): void {
        this.value = value;
    }
    public click(): void {
        debugger;
        this.value = "child new value";
        // event just forces angular to re run change detection
    }
    public registerOnChange(fn: (_: any) => void): void {
        this.onChange = fn;
    }
    public registerOnTouched(fn: () => void): void {
        this.onTouched = fn;
    }
    ngOnInit(): void {}
}
JavaScript

 

RAJESH GAMI - Blog

Digital Signature Pad in Angular | RAJESH GAMI

  What is Signature Pad? Signature Pad could be a JavaScript library for drawing fancy signatures. It supports HTML5 canvas and uses variabl...