Higher-order functions are functions that take other functions as arguments or return functions as their results.

  1. In the below example we Search employee by Location using Predicate.
  2. If we are not using HOF we need to assign new predicate to variable each and everytime like empFromDelhi
  3. Instead of doing that we have a HOF getEmpByLocation which takes location as string in arguments and returns function in its return type
public class HigherOrdFns {
    public static void main(String[] args) {
        Employee objEmp1 = new Employee(101, "Mugil", 30, "Chennai", "600018", 5, 5000);
        Employee objEmp2 = new Employee(102, "Mani", 33, "Chennai", "600028", 4, 6000);
        Employee objEmp3 = new Employee(103, "Madhu", 32, "Chennai", "600054", 6, 10000);
        Employee objEmp4 = new Employee(104, "Vinu", 29, "Bangalore", "500234", 5, 15000);
        Employee objEmp5 = new Employee(105, "Srini", 40, "Delhi", "622142", 10, 7000);
        Employee objEmp6 = new Employee(106, "Dimple", 35, "Delhi", "622142", 5, 8000);

        List<Employee> arrEmployee = Arrays.asList(objEmp1, objEmp2, objEmp3, objEmp4, objEmp5, objEmp6);

        Predicate<Employee> empFromDelhi = employee -> employee.getLocation().equals("Delhi");

        arrEmployee.stream().filter(empFromDelhi).forEach(System.out::println);
        arrEmployee.stream().filter(getEmpByLocation("Chennai")).forEach(System.out::println);
        arrEmployee.stream().filter(getEmpByLocation("Bangalore")).forEach(System.out::println);
    }

    //Higher Order function which return function as return type
    private static Predicate<Employee> getEmpByLocation(String location) {
        return employee -> employee.getLocation().equals(location);
    }
}

Swagger Consist of Three Parts

  1. swagger-editor– Helps in editing yml file as per Open API Specification
  2. swagger-ui– dist folder helps in circulating API documentation
  3. swagger-codegen

Installing Swagger in Local
Swagger needs http-server. We would use node http-server. We should navigate to the swagger editor folder and start the http-server.

>>npm install -g http-server
>>npm install
>>http-server swagger-editor -a 127.0.0.1 -p 8090
>>http-server swagger-ui -a 127.0.0.1 -p 8091

For the API Documentation we can copy and ship the dist folder in swagger-ui folder. We would have already placed the yaml file which we have created in swagger-editor in swagger-ui folder. Now we should edit the index.html file in swagger-ui folder as below to point to out yml file

index.html

.
.
window.onload = function() {
  // Begin Swagger UI call region
  const ui = SwaggerUIBundle({
  url: "EmpMgmt.yaml",
  dom_id: '#swagger-ui',
   deepLinking: true,
.
.

Presuming the project has Documentation in api-docs folder we can now start the server as below

>>D:\Projects\workspace\EmpMgmt> http-server api-docs -a 127.0.0.1 -p 8091

Refernce for OpenAPI Specification
https://github.com/OAI/OpenAPI-Specification/tree/main/versions

ng serve Loads the project in server
ng test Carries out unit testing.
karma.config.js – defines configuration of test runner
ng lint Checks for violation in coding standard. Checks whether it conforms to standard as defined in tslint.json
ng build creates dist folder in project. dist folder contains js files generated from ts files. The dist folder could be copied and added along with java app and deployed in web server for supporting front end. dist folder is one deployed at end of development I prod
ng e2e much more than unit test. It works by launching angular application in a headless chrome browser. The test are defined in e2e folder
ng new PROJECT_NAME –no-strict creates a new angular project mostly for Development You can toggle by setting strict:false in tsconfig.json
ng new PROJECT_NAME creates a new angular project
ng generate component COMPONENT_NAME generates a new component with component name
ng generate class models/CLASS_NAME generates a class in models folder
ng generate service SERVICE_NAME generates a service
Files and Folders Comments
src->app contains actual project code
dist Contains final distributable js file generated as result of ng build
e2e Contains script for end to end testing
environments Contains the details specific to environment
tsconfig.json code written in ts should be converted to js to get interpretted by browser. This would be configured in tsconfig,json
package.json frameworks and packages needs to execute ng command are defined here
src->main.ts, index.html Responsible for bootstrapping angular application
polyfills.ts take care of browser incompatibility
style.css specifies global application style
test.ts starting point for running unit test
app-routing.module.ts file where all routes are defined
  1. main.ts is starting point of angular application
  2. main.ts refers to app.module.ts which tells the components to be considered during bootstrap
  3. the component by default would be AppComponent which loads the app.component.html
  4. index.html is the root html file which loads the whole app in broswer.When you inspect index.html it would have the same code as one in editor showing loading. The JS files would replace the content in index.html once it gets loaded.Its the same js file which gets generated during ng build placed in dist folder
  5. All components newly added should be registered in app.module.ts. This file is like registry which would help angular to keep track of components
main.ts -> app.module.ts -> Check for bootstrap component

5 ways of passing data between html and components

1 Parent Child @Input
2 Child Parent @Output
3 HTML Form Component Using @Viewchild and ElemRef
4 HTML Form Component @ng-content and @ContentChild
5 HTML Form Component [(ngModel)]

3.@Viewchild and ElemRef
test.component.html

.
.
<input type="text" id="name" class="form-control" #ingName>
.

test.component.ts

export class ShoppingEditComponent implements OnInit 
{
  @ViewChild('ingName') strNameOfIngredient: ElementRef;
  
  ngOnInit(): void 
  {
    console.log(this.strNameOfIngredient.nativeElement.value);
  }
}

Angular Components

  1. Decorators – Passing value between components

    1. Passing Value from Parent to Child – @Input
    2. Passing Value from Child to Parent – @Output
  2. Change Detection
  3. Value Projection

Sending value from Parent to Child Component – Input decorator

  1. There may be times where the value needs to be passed between Parent Component and Child Component
  2. Passing Value occurs by parent HTML app.component.html by defining value to be passed and by using @Input() annotation
  3. In the app.component.ts we are sending a Student object with variable name classRepSent
  4. In the registration.component.ts we are receiving a Student object with variable name classRepReceive
  5. app.component.html is the one which enables passing of variable. The passed variable(classRepSent) is at the right side of bracket “classRepSent” and received variable is on left side in square brackets [classRepReceive]

Sending value from Parent to Child Component
app.component.ts

export class AppComponent {
  public classRepSent:Student; 

  constructor(){
    this.classRepSent= new Student(110, 'Baalaaji', 31, 74, 65,55,64,84); 
  }
  .
  . 
}

registration.component.ts

import { Component, OnInit, Input } from '@angular/core';
.
.
export class RegistrationComponent implements OnInit {
  @Input() public classRepReceive:Student; 
  .
  . 
  ngOnInit() {   
    console.log(this.classRepReceive);                    
  }

app.component.html

<app-registration [classRepReceive]="classRepSent"></app-registration>

Sending value from Child to Parent Component – Output decorator

  1. For Sending value from child component to parent component we use EventEmitter and @Output annotation
  2. We want to send a Student object from Child Component(registration.component.ts) to parent Component(app.component.ts)
  3. Value from child component to parent component could not be sent at time of loading since the components are loaded in hieracial order – parent to child. hence it should be triggered manually in our case we are doing it by using a button
  4. We use a button in registration.component.html which calls a function sendStudent that inturn calls the emitter to send a student with value anand to parent
  5. The Same would be received in app.component.ts using receiveStudent function
  6. Note we are sending a event and receiving a student object. In the HTML we have used receiveStudent as getting event rather than receiving a student object

app.component.ts

export class AppComponent {
.
.
receiveStudent(student:Student){
  console.log(student);
}
.
}

registration.component.ts

import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
.
.
export class RegistrationComponent implements OnInit {
  .
  .
  .
  @Output() private student:EventEmitter<Student> = new EventEmitter<Student>();
  .
  .
  sendStudent(pEvent)
  {
    this.student.emit(new Student(106, 'Anandh', 23, 31, 65,55,89,84));
  }
}

app.component.html

<app-registration [classRepReceive]="classRepSent" (student)="receiveStudent($event)"></app-registration>

registration.component.html

.
.
.
<td><input type="button" name="btnCallParent" id="btnCallParent" value="Send Student" (click)="sendStudent($event)"/></td>
.
.
.

Change Detection using ChangeDetection Strategy

  1. Every time angular notices an event it goes through each and every component tree to check the change in the attribute of object. In very large application this could be a bottleneck and going to have a hit on performance.To avoid the unnecessary check on all component we can let angular know the possible components which could be affected during operation.
  2. ChangeDetectionStrateg.default- is the change strategy available to component by default. When a object is created by parent component and shared with child component
    then any change in attribute of object made in parent component would be immediately available to child component and updated in model
  3. ChangeDetectionStrateg.OnPush – is forcing angular to refresh view of child only when the object is accessed.(Note:This object is created in Parent). Though the child component
    would have the updated value it wont be shown up in view.

  1. The object which is created in parent is shared in between parent and child.
  2. In the above Screen the Counter as in Parent and Counter as in Child would have the same value irrespective of whether you click increment from parent or increment from childwhen the ChangeDetection Strategy is set to default.When the ChangeDetection Strategy is set to default then incrementing counter using Increment Counter From Parent and Increment Counter From child would have the same effect.
  3. The Counter as in Parent and Counter as in Child would be changed immediately and reflected in screen. This is nature of angular to detect refresh all component when attribute of object used in one component is changed.But in big application many component need not be refreshed and we could tell angular what component needs to be checked
  4. When the ChangeDetection Strategy is set to onPush in child then the incrementing the parent counter wont be reflected in Counter as in Child.The updated value would be shown in child only when object is accessed by child component. Otherwise, increment counter in child would display updated value in Counter as in Child

ParentcounterComponent.ts

import { Component, OnInit } from '@angular/core';
import { Counter } from 'src/app/model/counter';

@Component({
  selector: 'app-parentcounter',
  templateUrl: './parentcounter.component.html',
  styleUrls: ['./parentcounter.component.css']
})
export class ParentcounterComponent implements OnInit {

  constructor() { }

  public counter : Counter;

  ngOnInit(): void {
    this.counter = new Counter(1);
  }


  increaseCounter()
  {        
    this.counter.value +=2;
    console.log(this.counter.value);
  }

  createNewCounter(){
    this.counter = new Counter(1);
  }
}

CounterComponent.ts

import { Component, OnInit, Input, Output, EventEmitter, ChangeDetectionStrategy } from '@angular/core';
import { Counter } from 'src/app/model/counter';

@Component({
  selector: 'app-counter',
  templateUrl: './counter.component.html',
  styleUrls: ['./counter.component.css']
})
export class CounterComponent implements OnInit {

  @Input() public counterVal: Counter;
  @Output() private counterEmitter: EventEmitter<Counter>;   

  ngOnInit(): void {    
  }

  increaseChildCounter()
  {
    console.log(this.counterVal.value);
    this.counterVal.value +=1;
  }

  sendCounterToParentComp(){     
    this.counterEmitter.emit(this.counterVal);
  }
}

parentcounter.component.html

<span>Counter as in Parent - {{counter.value}}</span><br/>    <br/>    
<app-counter [counterVal]="counter"></app-counter><br/>    
<button (click)="increaseCounter()">Increment Counter From Parent</button><br/> <br/>       
<button (click)="createNewCounter()">Create New Counter Object </button><br/>  <br/>     

counter.component.html

<span>Counter as in Child - {{counterVal.value}}</span><br/>    <br/>    
<button (click)="increaseChildCounter()">Update Counter From Child</button><br/>    

Custom Attribute Directive

  1. Below is a Custom Attribute Directive which applies Background color to HTML Elements
  2. However we could not apply anylogic based on which directive would apply like checking row is even or odd
  3. Entry should be made in app.modules.ts for new directives created so it would be available

EvenrowHighlighterDirective.ts

import {AfterViewInit, Directive, ElementRef, OnInit} from '@angular/core';

@Directive({
  selector: '[appevenrow]'
})
export class EvenrowHighlighterDirective implements  OnInit, AfterViewInit{
  constructor(public elementRef: ElementRef) {
  }

  ngOnInit(): void {
    this.elementRef.nativeElement.style.backgroundColor = 'gray';
  }

  ngAfterViewInit(){
    //Add the above code here if ng-content and @child-content is used
  }
}

Custom Structural Directive

  1. In below code we replace the functionality of ngIf using custom structural directive which checks for condition based on value set in isPresent
  2. Similar to ElementRef, TemplateRef gives access to template
  3. ViewContainer is a reference to the place where the Custom Structural Directive is placed
  4. One of the key thing while using structural directive is selector, @Input should have the same name. This reason behind this is due to the fact that *ngIf would be convered to ng-template before rendering.ng-template works on refernce basis within html. So when reference and directive name are different it would end up in error

test.component.ts

import {Directive, Input, TemplateRef,  ViewContainerRef} from '@angular/core';

@Directive({
  selector: '[appDounless]'
})
export class DounlessDirective {

  constructor(private templateRef: TemplateRef<any>, private vcRef: ViewContainerRef) { }

  @Input() set appDounless(condition: boolean){
    if(condition) {
      this.vcRef.createEmbeddedView(this.templateRef);
    }else{
      this.vcRef.clear();
    }
  }
}

test.component.ts

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

export class testComponent implements OnInit {

  public isPresent = true;

  ngOnInit() {
  }
}

test.component.html

<p appevenrow> This is Custom Attribute Directive</p>
<p *appDounless="isPresent">This is Custom Structural Directive</p>

Output

To pass data between components at the same level under parent, I.E. passing data between two children within the same parent we use @Input and @Output and pass the value through the tags.

The Other option is using EventEmitter as variable in Service and emitting value from component1 and getting value in component2.

  1. In the below code we are passing data from list-person.component.ts to add-person.component.ts
  2. We are calling instance of personcrudService to call a function which emits event which is received by ListPersonComponent OnInit() method
  3. In add-person.component.ts we subscribe to the event by using instance of personcrudService

personcrud.service.ts

import {EventEmitter, Injectable, OnInit} from '@angular/core';
import {LoggingServiceService} from './logging-service.service';

@Injectable({
  providedIn: 'root'
})
export class PersoncrudService{  
  statusUpdated: EventEmitter<string> = new EventEmitter<string>();

  constructor(public loggingServiceService: LoggingServiceService) {}

  updatePerson(id: number, status: boolean){
    .
    . 
    this.statusUpdated.emit(this.arrPersons[id].name);
    .
    .
  }
}

list-person.component.ts

@Component({
  selector: 'app-list-person',
  templateUrl: './list-person.component.html',
  styleUrls: ['./list-person.component.css'],
  providers: [LoggingServiceService]
})
export class ListPersonComponent implements OnInit {
  constructor(private personcrudService: PersoncrudService,
              private loggingServiceService: LoggingServiceService) { }

  ngOnInit(): void {
  }

  updateStatus(i, status){
    this.personcrudService.updatePerson(i, status);
    this.loggingServiceService.logStatusOfPerson(status);
  }
}

add-person.component.ts

@Component({
  selector: 'app-add-person',
  templateUrl: './add-person.component.html',
  styleUrls: ['./add-person.component.css']
})
export class AddPersonComponent implements OnInit {
  constructor(private personcrudService: PersoncrudService) {
  }

  ngOnInit(): void {
    this.personcrudService.statusUpdated.subscribe(
      (name: string) => alert(name + ' has been updates')
    );
  }
}

Below we have a Student class with Private Class Variable(id and name), Service and Private Methods.

Student.java

public class Student {
    private Integer id;
    private String name;

    @Autowired
    private StudentService studentService;

    private String getStudentDetails(){
      return "id: " + getId() + "; name: " + getName();
    }  
}

Mocking a Private Field
we cannot access the private field id to assign a value for testing, because there isn’t a public setter method for it.
We can then use ReflectionTestUtils.setField method to assign a value to the private member id

StudentTest.java

@Test
public void setValueWithNoSetter() {
    Student student = new Student();
    ReflectionTestUtils.setField(student, "id", 101); 
    assertTrue(student.getId().equals(101));
}

Mocking a Private Method
In a similar way we can invoke private method – getStudentDetails() as below in student class
StudentTest.java

@Test
public void whenNonPublicMethod_thenReflectionTestUtilsInvokeMethod() {
    Student student= new Student ();
    ReflectionTestUtils.setField(student, "id", 101);
    ReflectionTestUtils.setField(student, "name", "Mugil");
 
    assertTrue(ReflectionTestUtils.invokeMethod(student, "employeeToString").equals
                 ("id: 101; name: Mugil"));
}

Mocking a Private Dependencies
StudentTest.java

@Test
public void whenNonPublicMethod_thenReflectionTestUtilsInvokeMethod() 
{
   Student student = new Student();
   StudentService studService = mock(StudentService.class);
   when(studService.getStudentStatus(student.getId())).thenReturn("Active");

   ReflectionTestUtils.setField(student, "studentService", studService);

.
.
}

Below we have class – ClassA which contains the actual method – MethodA to be tested. MethodA has call to two dependent
ClassA.java

package com.mugil.org;

public class ClassA {
    public ClassADep1 dependency1;
    public ClassADep2 dependency2;

    public ClassA(ClassADep1 dependency1, ClassADep2 dependency2) {
        this.dependency1 = dependency1;
        this.dependency2 = dependency2;
    }

    public boolean MethodA(){
        System.out.println("I am going to call Dep1Method");
        dependency1.Dep1Method();

        System.out.println("I am going to call Dep2Method");
        dependency2.Dep2Method();

        return true;
    }
}

ClassADep1.java

package com.mugil.org;

public class ClassADep1 {
    public void Dep1Method(){
        System.out.println("This is ClassADep1 Method getting called");
    }
}

ClassADep2.java

package com.mugil.org;

public class ClassADep2 {
    public void Dep2Method(){
        System.out.println("This is ClassADep2 Method getting called");
    }
}

Use @Mock when you want to just test the functionality externally without actually calling that method.If you want to be safe and avoid calling external services and just want to test the logic inside of the unit, then use mock.

Using @Mock annotation for Dependency
ClassATest.java

package com.mugil.org;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import static org.junit.jupiter.api.Assertions.*;

@ExtendWith({MockitoExtension.class})
class ClassATest {
    @InjectMocks
    ClassA classA;

    @Mock
    ClassADep1 dependency1;

    @Mock
    ClassADep2 dependency2;

    @Test
    void methodA() {
        assertEquals(true, classA.MethodA());
    }
}

Output

I am going to call Dep1Method
I am going to call Dep2Method

Use @Spy when you want to test the functionality externally + internally with the very method being called. If you want to call an external service and perform calling of real dependencies, or simply say, you want to run the program as it is and just stub specific methods, then use spy.

Using @Spy annotation for Dependency
ClassATest.java

package com.mugil.org;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Spy;
import org.mockito.junit.jupiter.MockitoExtension;

import static org.junit.jupiter.api.Assertions.assertEquals;

@ExtendWith({MockitoExtension.class})
class ClassATest {
    @InjectMocks
    ClassA classA;

    @Spy
    ClassADep1 dependency1;

    @Spy
    ClassADep2 dependency2;

    @Test
    void methodA() {
        assertEquals(true, classA.MethodA());
    }
}

Output

I am going to call Dep1Method
This is ClassADep1 Method getting called
I am going to call Dep2Method
This is ClassADep2 Method getting called