Monday, October 30, 2023

Validations in Angular Part 1 [MDF Validations]

Why we need Forms?

Forms are the main building blocks of any type of application. When we use forms for login, registration, submission. Help request, etc., it is necessary that whatever forms we are developing, they should be user friendly. And it should have the indication of what went wrong by display user friendly message, etc.


Ensuring proper data[input] from user is called "validation"

  eg: username cannot be blank
      mobile requires 10 digit number

*Angular is providing built-in support[code] for validations, this makes developer
 job easy and faster
*Angular supports 2 types of validations
 1.MDF[Model Driven Form] validations
 2.TDF[Template Driven Form] validations

MDF validations:
----------------
*Validations applied to model properties with in a component class is called
 "MDF validations"

*MDF will separate validations from UI, this makes unit testing validations easy
 and provides programming flexibility

*programming flexibility means dynamic controls creation with validation[s] is possible and validations can be referenced | verified from router guards[comes later in the routing]

*MDF validations is also called "ReactiveForm Validations"

*Angular is providing ReactiveFormsModule with @angular/forms package with set of classes to work with MDF validations.


For this, first, we need to create the model using Agular's inbuilt classes like formGroup and formControl and then we need to bind that model to the HTML form.



1.Form Control class--this is used to declare a model property to set | get
                      form control data by applying validation

2 Form Group class --this is used to build a model with collection of props.


3.FormArray class --this is used to create an array of form controls (or) form groups
                      (or) nested form array

     ->formgroup will be serialized into an object
       formarray will be serialized into an array

     ->formgroup doesn't support dynamic controls creation
       formarray supports dynamic controls creation

In order to use Reactive Forms, you need to import ReactiveFormsModule into the applications root module i.e. app.module.ts

4.Validators class--this is providing collection of static methods to perform
                     different types of validations
                    
i. required-   this will validate whether input is provided or not
                               [applied for mandatory fields]
ii. minlength(n)-this will validate user input for minimum no of chars

iii.maxlength(n)-this will validate user input for maximum no of chars.
                   
iv.email--this will validate user input for an email id.
                    
v.pattern(expression)--this will validate user input against an
                                           expression
                      
eg:

                       [0-9]{10} --expression | pattern to accept 10 digit number
                [A-Za-z.\\s]{1,} --expression to accept a string with lower |upper |dot |spaces with 1 to any
                        


Form Group, Form Array and Form Control props | methods:
--------------------------------------------------
                    AbstractClass           --> base class
              [valid|invalid|..-->props]
                         |
   FormGroup      FormArray     FormControl --> derived classes
    class                  class               class 



1.valid-it will return true | false
        true-validation[s] is success
         
2.invalid-it will return true | false
         true-validation[s] is failed

3.touched-it will return true | false
         true-focus to control

4.untouched-it will return true  | false
         true-no focus to control

5.pristine-it will return true  | false
         true-control is not edited

6.dirty-it will return true | false
        true-control is edited

7.value-it will provide model props data
        <modelname | formgroupname>.value.<propname>

8.hasError('validationname')-it will return true|false
                             true-validation is failed 

  mobile--required validation
          pattern is 10 digit

  <span *ngIf="usermodel.controls['mobile'].invalid">
       error message-->common for required and pattern
  </span>

   (or)  

 <span  *ngIf="usermodel.controls['mobile'].hasError('required')">
       ...
 </span>

 <span  *ngIf="usermodel.controls['mobile'].hasError('pattern')">
       ...
 </span>


steps to work with mdf:
-----------------------
1.create|build a model with collection of props
  syntax:
  this.<modelname>=new FormGroup({
     <propname1>:new FormControl(initialvalue,[validation[s]]),
            ...
            },{updateOn:'change|blur|submit'});



this.userModel=new FormGroup(
     {
       firstname:new FormControl("",[Validators.required]),
       lastname:new FormControl("",[Validators.required]),
       emailid:new FormControl("xyz@gmail.com",[Validators.email])
     },{updateOn:'change'}
   );

2.bind model and props to template
   syntax:
       <form [formGroup]="modelname" ..>
          <input formControlName="propname">
              ..
       </form>


<form [formGroup]="userModel" (ngSubmit)="register()">
 firstname:<input formControlName="firstname">
        <span *ngIf="userModel.controls['firstname'].invalid">
            enter firstname
        </span>
3.place|import ReactiveFormsModule into AppModule
















Features of Reactive Forms:
  1. More flexible, but need a lot of practice
  2. Handles any complex scenarios.
  3. No data binding is done (Immutable data model preferred by most developers).
  4. More component code and less HTML Markup.
  5. Easier unit testing.
  6. Reactive transformations can be made possible such as
  7. Handling a event based on a denounce time.
  8. Handling events when the components are distinct until changed.
  9. Adding elements dynamically.


Dependency Injection in Angular

 Injecting class dependencies through a constructor[or setter],rather than

 instantiating an object directly is called DI

Dependency Injection is the heart of Angular Applications. The Dependency Injection in Angular is a combination of two terms i.e. Dependency and Injection.

DI will provide singleton behavior to a service class in angular
singleton means creating single object of a service class and used for
 different purposes, this makes single object reusable across different
 components

Dependency: Dependency is an object or service that is going to be used by another object.

Injections: It is a process of passing the dependency object to the dependent object. It creates a new instance of the class along with its require dependencies.


Example

Employee Service

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class EmployeeService {

  constructor() { }

  getEmployeeDetails(): any[] {
    return [
      {
        ID: 'emp101', FirstName: 'Uday', LastName: 'Kumar',
        Branch: 'CSE', DOB: '29/02/1988', Gender: 'Male'
    },
    {
        ID: 'emp102', FirstName: 'Anurag', LastName: 'Mohanty',
        Branch: 'ETC', DOB: '23/05/1989', Gender: 'Male'
    },
    {
        ID: 'emp103', FirstName: 'Priyanka', LastName: 'Dewangan',
        Branch: 'CSE', DOB: '24/07/1992', Gender: 'Female'
    },
    {
        ID: 'emp104', FirstName: 'Hina', LastName: 'Sharma',
        Branch: 'ETC', DOB: '19/08/1990', Gender: 'Female'
    },
    {
        ID: 'emp105', FirstName: 'Sambit', LastName: 'Satapathy',
        Branch: 'CSE', DOB: '12/94/1991', Gender: 'Male'
    }
    ];
  }
  getTitle():string {
    return "Rajakonda Uday Kumar"
  }
}


.ts Changes


import { Component } from '@angular/core';
import { EmployeeService } from '../employee.service';

@Component({
  selector: 'app-contact',
  templateUrl: './contact.component.html',
  styleUrls: ['./contact.component.css'],
  providers:[EmployeeService]
})
export class ContactComponent {
employee:any[] | undefined
pageTitle: string | undefined;
private _employeeService: EmployeeService | undefined;
constructor(employeeService:EmployeeService) {
  this._employeeService=employeeService;
}
ngOnInit() {
  this.employee=this._employeeService?.getEmployeeDetails();
  this.pageTitle = this._employeeService?.getTitle();
}
}



.html Changes

<h2>{{pageTitle}}</h2>
<table>
    <thead>
        <tr>
            <th>ID</th>
            <th>First Name</th>
            <th>Last Name</th>
            <th>Branch</th>
            <th>DOB</th>
            <th>Gender</th>
        </tr>
    </thead>
    <tbody>
        <tr *ngFor='let emp of employee'>
            <td>{{emp.ID}}</td>
            <td>{{emp.FirstName}}</td>
            <td>{{emp.LastName}}</td>
            <td>{{emp.Branch}}</td>
            <td>{{emp.DOB}}</td>
            <td>{{emp.Gender}}</td>
        </tr>
    </tbody>
</table>


Output













Understanding Above Code

Here, in the .ts class, we need an instance of Employee Service to call the the getEmployeeDetails() and getTitle() method of Employee Service to get the list of employee data and the title.

 Here we are not creating an instance of Employee Service. Here, we declared a private field _employeeService of type EmployeeService. 

The constructor also has a parameter employeeService of type EmployeeService. Then the constructor initializing the private class field _employeeService with it’s parameter employeeService .

Then we are using this private field _employeeService to call the Employee Service methods getEmployeeDetails() and getTitle().

private _employeeService: EmployeeService | undefined;
constructor(employeeService:EmployeeService) {
  this._employeeService=employeeService;
}


Note:
 Here we are not getting an instance of the EmployeeService class. We are getting instance from constructor.

we can see that the constructor is provided with an instance of EmployeeService class, and then the constructor is assigning that instance to the private field _employeeService.


Who is creating and providing the instance to the constructor?
The answer is Angular Injector. When an instance of .ts class is created, the angular injector creates an instance of the EmployeeService class and provides it to the .ts  constructor. 
The constructor then assigns that instance to the private field _employeeService. We then use this private field _employeeService to call the EmployeeService methods getEmployeeDetails() and getTitle().


How does the angular injector knows about Employee Service?
For the Angular injector to be able to create and provide an instance of Employee Service , first we need to register the Employee Service with the Angular Injector. 
We register a service with the angular injector by using the providers property of @Component decorator or @NgModule decorator. We already know we decorate an angular component with @Component decorator and an angular module with @NgModule decorator.

Service with Angular Injector, this can be done at 3 levels

 1.Component  level
       this will implement DI to a parent component and child components,this
       is called "hierarchical DI", this requires providers option with component decorator
   syntax:
      @Component({
              ...
       providers:[servicename,..]
               })
        ...


Example

Technically,
If you are registering a service using the providers property of the @Component decorator then you are registering the service with an angular injector at the component level. The service is then available to that component and all of it’s children.

Syntax

@Component({
  selector: 'app-contact',
  templateUrl: './contact.component.html',
  styleUrls: ['./contact.component.css'],
  providers:[EmployeeService]
})


2 Module Level

if you register the service using the providers property of the @NgModule decorator then you are registering the service with an angular injector at the module level

Technically

this will implement DI to all the components present with in a
       module, this requires providers option with NgModule decorator
  syntax:
     @NgModule({
             ...
      providers:[servicename,..]
             })
          ...


In appModule.ts
























Example

module1[providers:myservice]
                 |
               object
                 |
  component1     component2           component3       component4
     |                                  |                                 |
constructor        constructor             constructor()
(obj:myservice)  (obj:myservice)    {
 {}                 {}                             obj=new myservice();
                                                         }  

3.application level
          this will implement DI to all the components present with in
          different modules of an application,this requires providedIn
          option with Injectable decorator
    syntax:
         @Injectable({
             providedIn:'root'
                    })


So, in our example, .ts has a dependency on EmployeeService. The .ts receives the dependency instance (i.e employeeService instance) from the the external source (i.e the angular injector) rather than creating the instance itself.


Advantages of Dependency Injection in Angular?
  1. Create applications that are easy to write and maintain over time as the application evolves
  2. Easy to share data and functionality as the angular injector provides a Singleton i.e a single instance of the service
  3. Easy to write and maintain unit tests as the dependencies can be mocked

Sunday, October 29, 2023

Angular Services

 Service is a class with business logic to perform validation | calculation by

 performing an ajax call to RestAPI

Service will separate business logic from UI, this leads to following advantages
 
1.reusability
       business logic will be reusable across components

 2.better code maintenance

 3.debugging|unit testing business logic will be easy.

Or 

The Angular Services are the piece of code or logic that are used to perform some specific task.
 A service can contain a value or function or combination of both. The Services in angular are
 injected into the application using the dependency injection mechanism

Why do we need a service in Angular?

Whenever you need to reuse the same data and logic across multiple components of your application, then you need to go for angular service. when ever you see the duplicated code across multiple components, then you need to think about refactoring the same logic or data access code into a service.


The logic or data is implemented in a services and the service can be used across multiple components of your angular application. So, services is a mechanism used to share the functionality between the components.

Without Angular Services, you would have to repeat the same logic or code in multiple components wherever you want this code or logic. Now think about the overhead in terms of time and effort required to develop, debug, test and maintain the duplicated code across multiple places instead of having that duplicated code at one central place like a service and reusing that service where required. 

steps to work with services

1.create a service
   syntax:
     export class <servicename>
     {
          ...
     }

2.consuming service with in component class
   syntax:
       class <componentname>
       {
          obj=new new <servicename>();
               ...
       }

In the above case unique object of service class will be created to
 each component, if the requirement is single object to all the
 components then go with Dependency Injection

The syntax to create angular service is given below.


import { Injectable } from '@angular/core';

@Injectable()

export class EmployeeServie {

}


Command to create a service

ng generate service Employee


Example






Employee-Service.ts


import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class EmployeeService {

  constructor() { }

  getEmployeeDetails(): any[] {
    return [
      {
        ID: 'emp101', FirstName: 'Uday', LastName: 'Kumar',
        Branch: 'CSE', DOB: '29/02/1988', Gender: 'Male'
    },
    {
        ID: 'emp102', FirstName: 'Anurag', LastName: 'Mohanty',
        Branch: 'ETC', DOB: '23/05/1989', Gender: 'Male'
    },
    {
        ID: 'emp103', FirstName: 'Priyanka', LastName: 'Dewangan',
        Branch: 'CSE', DOB: '24/07/1992', Gender: 'Female'
    },
    {
        ID: 'emp104', FirstName: 'Hina', LastName: 'Sharma',
        Branch: 'ETC', DOB: '19/08/1990', Gender: 'Female'
    },
    {
        ID: 'emp105', FirstName: 'Sambit', LastName: 'Satapathy',
        Branch: 'CSE', DOB: '12/94/1991', Gender: 'Male'
    }
    ];
  }
}


Note: The @Injectable() decorator in angular is used to inject other dependencies into the service. At the moment our service does not have any other dependencies, so, yo can remove the @Injectable() decorator and the service should works.

Next step, we are going to use that service in Angular APP.

  Three steps , we need to keep in mind before consuming a service

1 Import the service

import { EmployeeService } from '../employee.service';

2  Providers( Register the Service)

@Component({
  selector: 'app-contact',
  templateUrl: './contact.component.html',
  styleUrls: ['./contact.component.css'],
  providers:[EmployeeService]
})

3 Use the Service

constructor(private _employeeService:EmployeeService) {
  this.employee=_employeeService.getEmployeeDetails();
}



.TS Changes

import { Component } from '@angular/core';
import { EmployeeService } from '../employee.service';

@Component({
  selector: 'app-contact',
  templateUrl: './contact.component.html',
  styleUrls: ['./contact.component.css'],
  providers:[EmployeeService]
})
export class ContactComponent {
employee:any[] | undefined
constructor(private _employeeService:EmployeeService) {
  this.employee=_employeeService.getEmployeeDetails();
}
}

.html Changes

<table>
    <thead>
        <tr>
            <th>ID</th>
            <th>First Name</th>
            <th>Last Name</th>
            <th>Branch</th>
            <th>DOB</th>
            <th>Gender</th>
        </tr>
    </thead>
    <tbody>
        <tr *ngFor='let emp of employee'>
            <td>{{emp.ID}}</td>
            <td>{{emp.FirstName}}</td>
            <td>{{emp.LastName}}</td>
            <td>{{emp.Branch}}</td>
            <td>{{emp.DOB}}</td>
            <td>{{emp.Gender}}</td>
        </tr>
    </tbody>
</table>



   Output



Difference between Constructor vs ngOnInit() 

The ngOnInit is a method provided by Angular which is called after the constructor and is generally used to perform tasks related to Angular bindings. 

ngOnInit is the right place to call a service method to fetch data from a remote server. We can also do the same using a class constructor, but the thumb rule is  consuming should use ngOnInit instead of the constructor. As fetching data from a remote server is time consuming, the better place for calling the service method is ngOnInit.

In our example, the dependency injection is done using the class constructor and the actual service method call is issued from ngOnInit life cycle.




Kubernetes

Prerequisites We assume anyone who wants to understand Kubernetes should have an understating of how the Docker works, how the Docker images...