Monday, October 30, 2023

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.




Angular Routing with Parameters and how routing works

Route path can receive data from url with the help of parameter, this is
 similar to querystring concept of traditional web development

  http://../details.aspx?pid=p001----------->details.aspx
                                                  |
                                            Request.queryString["pid"]




Paraname should be prefixed with :,route path can have any numb of paras

Parameter value can be read with in component class using "ActivatedRoute" class

Syntax:
   this._activatedroute.ParamMap.subscribe((paras)=>{
                 paras.get("paraname")
                                                  });



How Angular Routing Works


angular router performs the following 7 steps

Step1: Parse the URL
Angular Router takes the browser URL and parses it as a URL tree. To parse the URL, the angular framework uses the following conventions:

  1. Slashes (/): slashes divides URL segments
  2. Parentheses (): Parentheses specify secondary routes
  3. Colon (:): A colon specifies a named router outlet.
  4. Semicolon (;): A semicolon specifies a matrix parameter
  5. Question Mark (?): A question mark separates the query string parameters.
  6. Hashtag (#): The hashtag specifies the fragment
  7. Double Slash (//): A double slash separates multiple secondary routes.

Step2: Redirect

Before Angular Router uses the URL tree to create a router state, it checks to see if any redirects should be applied. There are two kinds of redirect.

Local Redirect: When redirectTo does not start with a slash. Replaces a single URL segment. For example, {path:’one’, redirectTo:’two’}.

Absolute Redirect: When redirectTo starts with a slash, replaces the entire URL. For example, {path:’one’, redirectTo:’/two’}.

Step3: Identify the Router State

In this step, the Angular Router traverse the URL tree and matches the URL segments against the path configured in the Router Configuration. If a URL Segment matches the path of a route, the route’s child routes are matched against the remaining URL segments until all URL segments are matched. If no complete match is found, the router backtracks to find a match in the next sibling route.


Step4: Guard – run guards

At the moment, any user can navigate anywhere in the application. That’s not always the right thing to do. Perhaps the user is not authorized to navigate to the target component. May be the user must be login (authenticate) first. May be you should fetch some data before you display the target component.

ou might want to save pending changes before leaving a component. You might ask the user if its OK to discard pending changes rather than save them.

You can add guards to the route configuration to handle these scenarios.

Step5: Resolve

It resolves the required data for the router state.

Step6: Activate

It activates the Angular Components to display the page

Step7: Manage

Finally when the new router state has been displayed to the screen, Angular Router listens for URL changes and state changes. It manages navigation and repeats the process when a new URL is requested.


Kubernetes

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