angular ng module and aot

Angular NgModule AOT and DI


βœ‹ What is an alternative to the @Input and @Output decorator?

inputs and outputs selectors in component decorator are another way to define input and output properties, If we do like this we don’t need to import @Input and @Output.

inputs: [‘name’, ’empId’],
outputs: [‘changeName’, ‘updateId’]

import { Component, EventEmitter} from '@angular/core';
@Component({
	selector: 'app-employee',
	templateUrl: './employee.component.html',
	styleUrls: ['./employee.component.scss'],
	inputs: ['name', 'empId'],
	outputs: ['changeName', 'updateId']
})
export class EmployeeComponent {
  name: string;
  empId: string;
  changeName = new EventEmitter<string>();
  updateId = new EventEmitter<string>();

}


βœ‹ What are all types of Angular Modules?

Feature Module
Root Module
Core module
Shared module
Routing module


βœ‹ How AOT works behind the schene?

There are three phases of AOT compilation.

Phase 1 is code analysis.
Phase 2 is code generation.
Phase 3 is template type checking.


πŸ’‘ Phase 1 Code analysis

In the Code analysis phase, the compiler checks all decorators and other signatures. It also validates the binding expressions.

No Arrow Functions in Decorator property

Arrow functions can’t be used to assign values to the decorator properties. For example.
The Below code is invalid if you are using less Angular Version 5. And Compile reports an error that invites you to turn the arrow function into an exported function.

export class ClassA {
  printMe() {
    console.log('ClassA');
  }
}
providers: [{provide: OffShoreEmpService, useFactory: () => new ClassA()}]

So to fix this let’s rewrite above code with exported function.

export class ClassA {
  printMe() {
    console.log('ClassA');
  }
}

export function AFactory() {
  return new ClassA();
}

providers: [{provide: OffShoreEmpService, useFactory: AFactory}]

Note: In Angular version 5 and above that, we can write an arrow function and the compiler automatically performs this rewriting while emitting the .js file without reporting any error.

Code Folding

The collector (compiler), however, can evaluate an expression during collection and record the result in the .metadata.json, rather than the original expression.
For example, the collector can evaluate the expression {{7 + 8 + 1}} and replace it with the result, 16. This process is called folding. An expression that can be reduced in this manner is foldable.


πŸ’‘ Phase 2: code generation

In Phase 1 during analysis Collector generates a medadata.json file and then it generates code. The compiler understands all syntax forms that the collector supports, but it may reject if the semantics violate compiler rules.


πŸ’‘ Phase 3: Template type checking

This is the last step for AOT compiler and it has a feature of type checking off all expressions in templates and if any rule violates it catch errors. AOT performs this with help of the Typescript Compiler.
Now See below code, We have an onClick function with two arguments but in the TS file, we mentioned only One, so TS Compiler will catch this and report.

// HTML File
<button (click)="onClick(id, name)">Submit</button>

//TS file, -- TS Compiler will catch this (we didn't pass name parameter // here ) and report.
onCLick(id){
	console.log(id);
}


βœ‹ Difference between JIT and AOT?

Just-in-Time (JIT) – compiles angular application in the browser at runtime.
Ahead-of-Time (AOT) – compiles angular app at build time on the server.

JIT compiler is the default compiler when we do ng serve or simply do ng build. To Compile with AOT, we use ng build --prod command that is production mode (IF AOT enables in angular.json file) or use --aot flag.


βœ‹ What is AppModule?

App Module is a class decorated by ngModule that contains declarations, imports, exports, providers, and bootstrap features. It is also called the Root Module.


βœ‹ What is Feature Module?

Feature Module is a class decorated by ngModule and used to separate a complete feature to a new module. With feature modules, you can keep code related to specific functionality or feature separate from other code.
Feature modules import CommonModule instead of BrowserModule, which is only imported once in the root module.


βœ‹ What is CommonModule? Why its need to import in feature modules?

CommonModule contains all pipes, condition expressions like if, for, switch, and all basic directives, so to use these all in feature components we need to import this in every module.

import {CommonModule} from '@angular/common';


βœ‹ Why CommonModule is not required in the AppModule file?

Here is a catch and we have to think if there is no commonModule in appModoule file then how root level components ( defined in appModule ) are able to access all basic directives?

import { BrowserModule } from '@angular/platform-browser'; 

Browser Module provides all essential services to launch the application and only injected into the root module, and this also contains all required directives, classes of the common module. Since we don’t import BrowserModule in feature modules that’s why we import CommonModule in the feature Module.


βœ‹ What is the purpose of exports in ngModule?

@NgModule({
  declarations: [
      EmployeeComponent
  ],
  imports: [
      CommonModule,
      RouterModule.forChild(routes)
  ],
})
export class EmployeeModule { }

Let’s see the above Code. This is a Feature Module named EmployeeModule and this is imported in the AppModule.
EmployeeComponent is defined here so any other module can not access it. If you try to add this Employee component template in another component – it will give you a run time error like Template not defined.

So to access this in Root Level Components, we need to export this.
By this, we can access this component to another Module where we have injected EmployeeModule.

exports: [EmployeeComponent]


βœ‹ Difference between forRoot vs forChild?

forRoot

forRoot is available inside the app.routing.module.ts file & forChild is available inside in feature routing module file.
for Root registers the specified routes, and creates an instance of the router service, and registers it with the angular dependency injector.

forChild

forChild is available inside in feature routing module file. It registers the specified routes and tells angular to reuse the router service instance that forRoot has created.
So that’s why angular ensures that there is one Router service that works as a singleton service.


βœ‹ Is route order matter?

{ path: 'home', component: HomeComponent},
{ path: '', redirectTo: 'home', pathMatch: 'full' },
{ path: '**', // this is wild card routes, 
  component: PageNotFoundComponent,
},
{ path: 'employee', component: EmployeeComponent }

yes, it matters for the wild card route. All routes defined below the wild card route will never execute because for all other routes wild card condition ''**' is true.


βœ‹ Is importing Modules in an order matters?

Yes. Order of importing modules matters.
we can see one most important example here. All features modules should be imported before appRoutingModule.

This is Feature Module

const routes = [
    {	path: 'employee', component: EmployeeComponent },
];

@NgModule({
  declarations: [
      EmployeeComponent
  ],
  imports: [
      CommonModule,
      RouterModule.forChild(routes)
  ]
})
export class EmployeeModule { }

This is App Routing Module

const routes: Routes = [
	{ path: 'home', component: HomeComponent},

	{ path: '', redirectTo: 'home', pathMatch: 'full' },
	{ path: '**', // this is wild card routes, 
    component: PageNotFoundComponent,
	}
];
@NgModule({
	imports: [
		RouterModule.forRoot(routes),
	],
	exports: [RouterModule],
})
export class AppRoutingModule {}

Below is the import section of the App Module file

 imports: [
    BrowserModule.withServerTransition({ appId: 'serverApp' }),
    AppRoutingModule,
    EmployeeModule
  ],

So now if we try to navigate route /employee, it will redirect to PageNotFound component. Surprise….

Here we can see, we have imported EmployeeModule after AppRoutingModule that’s why all routes of app routing will load first and then routes of EmployeeModule will load after that. And because of this our wildcard route ‘**’ is true for all values.
To fix this we have to import EmployeeModule before AppRoutingModule.


βœ‹ What are the major requirements to lazy load a module?

There are two requirements to lazy load a module.

  1. To implement lazy load, All the routes in that feature module should have the same route prefix.
  2. The module should not be referenced in any other module otherwise it will be load as eager.

Student routing module file

const routes = [ 
 { path: 'create', component: StudentCreateComponent},
 {path: 'list', component: StudentListComponent}
]

App Routing Module > See below code for every route inside StudentModule, there is the same prefix named student.

{
 path: 'student', loadChildren: './student/student/module#StudentModule'
}


βœ‹ Explain Shared Module in Angular?

You can put commonly used directives, pipes, and components into one module and then import just that module wherever you need it in other parts of your app. By creating shared modules, we can organize and streamline code.

Rules to create Shared Module >

  • SharedModule should be imported by all other Feature Modules which need its shared functionality.
  • Shared NgModules should not include providers
  • SharedModule should not import or export modules that have providers.
  • May re-export other common angular modules like CommonModule, FormModule, etc.


βœ‹ –flat option in Angular CLI command?

ng g c home --flat (so this will not create home folder seperatly and will add home component inside app folder only)


βœ‹ What is Dependency Injection (DI)?

To define a class as a service in Angular, use the @Injectable() decorator to provide the metadata that allows Angular to inject it into a component as a dependency. And we add this service into a Component with its constructor function that is called DI.

constructor(private service: HeroService) { }

When Angular discovers that a component depends on a service, it first checks if the injector has any existing instances of that service. If an instance does not exist, angular create a new instance of that service by using registered providers and adds it to the injector before returning service to angular.

Angular NgModule AOT and DI


βœ‹ What are Entry components and How many types of entry components in angular?

There are components that are included in the template and that’s why called declarative. Additionally, there are some components that you load imperatively, that is called, entry components.

There are two main kinds of entry components:

The bootstrapped root component.
A component you specify in a route definition.


The bootstrapped root component

A bootstrapped component is an entry component that Angular loads into the DOM during the bootstrap process (application launch). Other entry components are loaded dynamically by other means, such as with the router.

@NgModule({
  declarations: [
    AppComponent
  ],
  bootstrap: [AppComponent] // bootstrapped entry component
})

A component you specify in a route definition.

The second kind of entry component occurs in a route definition like this:

const routes: Routes = [
  {
    path: '',
    component: StudentListComponent
  }
];

All router components must be entry components but we don't need to specify this into entry component manually. Angular Compiler is smart enough to recognize that this is a router definition and automatically add the router component into entry components.

The entryComponents array

If your app happens to bootstrap or dynamically load a component by type imperatively, you must add it to entryComponents explicitly. This is depreciated in angular 9 with IVY.


βœ‹ What are all Types of providers?

The Angular Dependency Injection provides several types of providers.

Class Provider : useClass
Value Provider: useValue
Factory Provider: useFactory
Aliased Class Provider: useExisting

For more details with Example. Please read here…
https://www.jsmount.com/useclass-usevalue-usefactory-useexisting/


βœ‹ What is OnInit?

OnInit is an interface and is a life cycle hook that used to initialized all data-bound properties. Define a ngOnInit() method to handle any additional initialization tasks.

interface OnInit {
  ngOnInit(): void
} 

Angular NgModule AOT and DI

Angular NgModule AOT and DI

Leave a Reply

Your email address will not be published.