//
Question 1: What are Angular decorators and how do they work?
//
Answer:
//
Decorators in Angular are design patterns used to define metadata about
classes, methods, properties, and parameters. They are prefixed with the
"@" symbol and used to attach specific functionality to the element
they are decorating. Angular uses these decorators to understand the structure
and behavior of different elements like components, directives, pipes, etc.
//
Example:
import
{ Component, Input } from '@angular/core';
@Component({
selector: 'app-example',
template: '<h1>Hello,
{{name}}</h1>',
})
export
class ExampleComponent {
@Input() name: string;
}
//
Question 2: What is Angular's dependency injection and how does it work?
//
Answer:
//
Dependency Injection (DI) is a design pattern used in Angular to manage
dependencies of various components and services. Angular's DI framework allows
you to inject dependencies into a component or service, rather than having the
component/service create them itself. This promotes better modularity and ease
of testing.
//
Example:
import
{ Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export
class DataService {
getData() {
return ['Data 1', 'Data 2', 'Data 3'];
}
}
import
{ Component } from '@angular/core';
import
{ DataService } from './data.service';
@Component({
selector: 'app-root',
template: '<ul><li *ngFor="let
item of data">{{item}}</li></ul>',
})
export
class AppComponent {
data: string[];
constructor(private dataService: DataService)
{
this.data = this.dataService.getData();
}
}
//
Question 3: Explain the difference between Observable and Promise in Angular.
//
Answer:
//
Observables and Promises are used to handle asynchronous data. Promises handle
a single event when an async operation completes or fails, while Observables
are more powerful and can handle multiple events over time. Observables are
lazy, meaning they only execute when subscribed to, and provide multiple
operators to transform, filter, and combine streams of data.
//
Example:
import
{ Observable } from 'rxjs';
const
observable = new Observable(observer => {
setTimeout(() => {
observer.next('Hello from Observable!');
observer.complete();
}, 1000);
});
observable.subscribe({
next: value => console.log(value),
complete: () => console.log('Observable
complete'),
});
const
promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Hello from Promise!');
}, 1000);
});
promise.then(value
=> console.log(value));
//
Question 4: What is Angular CLI and how do you use it?
//
Answer:
//
Angular CLI (Command Line Interface) is a powerful tool that helps to
initialize, develop, scaffold, and maintain Angular applications. It provides
commands to create components, services, pipes, directives, and more, as well
as to build and serve the application.
//
Example Commands:
//
Create a new Angular project: `ng new my-angular-app`
//
Serve the application: `ng serve`
//
Generate a new component: `ng generate component my-component`
//
Question 5: How does Angular handle forms? Explain Template-driven vs. Reactive
forms.
//
Answer:
//
Angular supports two types of forms: Template-driven and Reactive forms.
Template-driven forms rely on directives in the template to create and
manipulate the form controls, suitable for simple forms. Reactive forms provide
a model-driven approach to handle form inputs, offering more control and
flexibility, suitable for complex forms.
//
Example of Template-driven form:
import
{ Component } from '@angular/core';
@Component({
selector: 'app-template-form',
template: `
<form #form="ngForm"
(ngSubmit)="onSubmit(form)">
<input name="name" ngModel
required>
<button
type="submit">Submit</button>
</form>
`
})
export
class TemplateFormComponent {
onSubmit(form: any) {
console.log(form.value);
}
}
//
Example of Reactive form:
import
{ Component, OnInit } from '@angular/core';
import
{ FormGroup, FormControl, Validators } from '@angular/forms';
@Component({
selector: 'app-reactive-form',
template: `
<form [formGroup]="form"
(ngSubmit)="onSubmit()">
<input
formControlName="name" required>
<button
type="submit">Submit</button>
</form>
`
})
export
class ReactiveFormComponent implements OnInit {
form: FormGroup;
ngOnInit() {
this.form = new FormGroup({
name: new FormControl('',
Validators.required),
});
}
onSubmit() {
console.log(this.form.value);
}
}
//
Question 6: What are Angular services and how are they used?
//
Answer:
//
Services in Angular are used to share data and logic across components. They
are singleton objects, meaning there is only one instance of the service in the
application. Services are typically used to encapsulate business logic,
interact with external APIs, or share state between components.
//
Example:
import
{ Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export
class LoggerService {
log(message: string) {
console.log(message);
}
}
import
{ Component } from '@angular/core';
import
{ LoggerService } from './logger.service';
@Component({
selector: 'app-root',
template: '<button
(click)="logMessage()">Log Message</button>',
})
export
class AppComponent {
constructor(private logger: LoggerService) {}
logMessage() {
this.logger.log('Hello from
AppComponent!');
}
}
//
Question 21: What is Module Federation in Angular?
//
Answer:
//
Module Federation is a feature introduced in Webpack 5 that allows multiple
independently built and deployed applications to form a single application. It
enables the sharing of code between applications at runtime, which helps in
creating micro-frontends or splitting a monolithic application into smaller,
manageable parts.
//
Example:
//
webpack.config.js for host application
const
ModuleFederationPlugin =
require('webpack/lib/container/ModuleFederationPlugin');
module.exports
= {
output: {
publicPath: 'http://localhost:3000/',
},
plugins: [
new ModuleFederationPlugin({
name: 'hostApp',
remotes: {
remoteApp:
'remoteApp@http://localhost:3001/remoteEntry.js',
},
shared: ['@angular/core',
'@angular/common', '@angular/router'],
}),
],
};
//
webpack.config.js for remote application
const
ModuleFederationPlugin =
require('webpack/lib/container/ModuleFederationPlugin');
module.exports
= {
output: {
publicPath: 'http://localhost:3001/',
},
plugins: [
new ModuleFederationPlugin({
name: 'remoteApp',
filename: 'remoteEntry.js',
exposes: {
'./Component': './src/app/component',
},
shared: ['@angular/core',
'@angular/common', '@angular/router'],
}),
],
};
//
Question 22: How do you configure Module Federation in Angular?
//
Answer:
//
To configure Module Federation in Angular, you need to adjust the Webpack
configuration for both the host and remote applications. Use the
ModuleFederationPlugin to define the exposed modules and the shared
dependencies.
//
Example:
//
angular.json modifications for custom Webpack configuration
{
"projects": {
"hostApp": {
"architect": {
"build": {
"builder":
"@angular-builders/custom-webpack:browser",
"options": {
"customWebpackConfig": {
"path":
"./webpack.config.js"
}
}
},
"serve": {
"builder":
"@angular-builders/custom-webpack:dev-server",
"options": {
"customWebpackConfig": {
"path":
"./webpack.config.js"
}
}
}
}
}
}
}
//
Question 23: What are the benefits of using Module Federation?
//
Answer:
//
Benefits of using Module Federation include:
1.
Independent deployment of micro-frontends.
2.
Improved scalability and maintainability.
3.
Sharing code between applications without duplication.
4.
Reduced bundle sizes by loading only required modules.
5.
Seamless updates and versioning for different parts of the application.
//
Question 24: What are some common use cases for Module Federation?
//
Answer:
//
Common use cases for Module Federation include:
1.
Micro-frontend architecture.
2.
Splitting a monolithic application into smaller, independently deployable
modules.
3.
Sharing libraries or components across multiple applications.
4.
Dynamic module loading at runtime based on user requirements.
//
Question 25: How do you share dependencies using Module Federation?
//
Answer:
//
Shared dependencies in Module Federation are specified in the Webpack
configuration under the `shared` property. This ensures that only one instance
of the shared dependency is loaded, avoiding duplication and version conflicts.
//
Example:
const
ModuleFederationPlugin =
require('webpack/lib/container/ModuleFederationPlugin');
module.exports
= {
plugins: [
new ModuleFederationPlugin({
name: 'app',
remotes: {},
exposes: {},
shared: {
'@angular/core': { singleton: true,
strictVersion: true, requiredVersion: 'auto' },
'@angular/common': { singleton: true,
strictVersion: true, requiredVersion: 'auto' },
},
}),
],
};
//
Question 26: How do you expose a module using Module Federation?
//
Answer:
//
To expose a module using Module Federation, you define the module in the
`exposes` property of the ModuleFederationPlugin in your Webpack configuration.
This makes the module available for other applications to consume.
//
Example:
const
ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');
module.exports
= {
plugins: [
new ModuleFederationPlugin({
name: 'remoteApp',
filename: 'remoteEntry.js',
exposes: {
'./Component': './src/app/component',
},
}),
],
};
//
Question 27: How do you consume a remote module using Module Federation?
//
Answer:
//
To consume a remote module using Module Federation, you define the remote
application and the module to be consumed in the `remotes` property of the
ModuleFederationPlugin in your Webpack configuration. Then, you can dynamically
import the module in your application code.
//
Example:
const
ModuleFederationPlugin =
require('webpack/lib/container/ModuleFederationPlugin');
module.exports
= {
plugins: [
new ModuleFederationPlugin({
name: 'hostApp',
remotes: {
remoteApp:
'remoteApp@http://localhost:3001/remoteEntry.js',
},
}),
],
};
//
Consuming the remote module in Angular
import
{ loadRemoteModule } from '@angular-architects/module-federation';
@NgModule({
imports: [
RouterModule.forRoot([
{
path: 'remote',
loadChildren: () =>
loadRemoteModule({
remoteEntry:
'http://localhost:3001/remoteEntry.js',
remoteName: 'remoteApp',
exposedModule: './Component',
}).then(m => m.RemoteComponent),
},
]),
],
})
export
class AppModule {}
//
Question 28: How do you handle version mismatches in Module Federation?
//
Answer:
//
Version mismatches in Module Federation can be handled using the
`strictVersion` and `singleton` properties in the `shared` configuration. These
properties enforce specific version constraints and ensure that only one
instance of the shared dependency is loaded.
//
Example:
const
ModuleFederationPlugin =
require('webpack/lib/container/ModuleFederationPlugin');
Comments
Post a Comment