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

 

As No Tracking With Entity Framework Core | RAJESH GAMI

Introduction 

Entity Framework's DbContext keeps track of changes made to an entity or object and ensures that the database is updated correctly when the context method SaveChange () is called. When you use an object query to retrieve entities, Entity Framework caches them and keeps track of the changes made to them until the savechanges method is called.

Entity Framework keeps track of query results that return an entity type. You may not want to track some entities because the data is used for display purposes only and no other operations such as inserts, updates, or deletes are performed. For example, display data in a read-only grid.
In the above scenario, untracked queries are useful. Execution is very fast due to the change tracking feature. There are several ways to achieve untracked queries.
 
No-Tracking query using AsNoTracking() extention method
 
The AsNoTracking() extension method returns a new query and the returned entity is not tracked by the context. This means that EF does not perform the additional task of saving the retrieved entity for tracking.
 
Example
  1. using (EntityModelContext context = new EntityModelContext())  
  2. {  
  3.     var employee = context.Employees.AsNoTracking().ToList();    
  4.   
  5.     var employee2 = context.Employees    
  6.                     .Where(p => p.Id >= 4)    
  7.                     .AsNoTracking().ToList();    
  8. }  
Changing tracking behavior at the context instance level
 
You can also change the default tracking behavior at the Context Instance level. The ChangeTracker class (defined as a property of the context class) has a property QueryTrackingBehavior that you can use to change the tracking behavior.
 
Example
  1. using (EntityModelContext context = new EntityModelContext())  
  2. {  
  3.     context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;  
  4.     ...  
  5.     ...  
  6. }  
If the result set does not contain the entity type, no tracking will be performed.
 
If the query result does not contain the entity type, it will not be tracked by the change tracker and no tracking will be performed. No tracking is performed in the following query. This query returns an anonymous type that contains some of the entity values.
  1. var data2 = context.Employees.Select(p => new  
  2.                 {  
  3.                     name = p.Name,  
  4.                     id = p.Id  
  5.   
  6.                 }).ToList();  
Because the result contains the entity type, the result set may not return the entity even if that entity is tracked by default. In the following query, the result is an anonymous type, but it is tracked because the employee instance is included in the result set.
  1. var data2 = context.Employees.Select(emp => new  
  2.                {  
  3.                    Id = emp.Id,  
  4.                 Employee = emp  
  5.   
  6.                }).ToList();  
No Tracking saves both execution time and memory usage. Applying this option is very important when retrieving large amounts of data from the database for read-only purposes.
 

    How to write in Hindi font (or other language font) in HTML | ASP.NET Core | Rajesh Gami

    How to write in Hindi font (or other language font) in HTML | ASP.NET Core

     
    This blog will show you how to read and write in Hindi (or you can use any language you want).
    This section describes how to use the Devlys_010 font to write Hindi in ASP.NET Core text fields. Therefore, follow the steps below.

    Step 1 
    Download Devlys_010 font in any format such as .ttf, .woff, etc. You can download from here 
    This is a ZIP file, so you can unzip it into a folder.

    Step 2 
    Open the Asp.Net Core project and create a new folder under CSS. Give the folder a name like Fonts.
    Paste the downloaded fonts into the Fonts folder. Then create a CSS file and name it font.css.
     
    How to write in Hindi (Or another font) in Asp.Net Core 
     

    You can see that we have added a screenshot here. I inserted the fonts in ttf format and created font.css in the newly created "Fonts" folder.

    Step 3 
    Now open font.css in the editor. Next, let's add fonts to the project using @ font-face. Therefore, write the CSS code in font.css as follows:
    1. @font-face {  
    2.     font-family'Devlys_010';  
    3.     srclocal('Devlys_010'),url('./Devlys_010.ttf'format('truetype');  
    4. }  
    Step 4
    Next, create a new CSS class under @ font-face in font.css and add the font family used by @font-face.
    1. .hFont {  
    2.     font-family'Devlys_010' !important;  
    3. }  
    Now you can see all the CSS code in font.css.
    1. @font-face {  
    2.     font-family'Devlys_010';  
    3.     srclocal('Devlys_010'),url('./Devlys_010.ttf'format('truetype');  
    4. }  
    5.   
    6. .hFont {  
    7.     font-family'Devlys_010' !important;  
    8. }  
    Now I added the .hFont class. You can change this name.

    Step 5
     
    Next, go to the cshtml page where you want to write the Hindi font. So if you use the text input type, just add the hFont class as follows:
    Then add CSS to the header to get the CSS code.
    1. <link href="~/css/fonts/font.css" rel="stylesheet" />  
    Now add a CSS class to create a Hindi font. See the code below. Added hFont class to input type.
    1. <input asp-for="@Model.AdminMaster.AdminName" class="form-control hFont" id="txtAdminName" />  

    2. OR

    3. <input type = "text" class="form-control hFont" id="txtAdminName" />  
    Note
    You can use other fonts just by adding and using fonts in CSS. Also, use language fonts such as Gujarati, Marathi, Urdu, or other languages.

    Reference from my C# Corner blog : C# Corner Blog Link

    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...