MEAN Unit-5
MEAN Unit-5
MEAN STACK UNIT-04 application is divided into reusable and self-contained components. This promotes modular
development, code reusability, and maintainability.
➢ Two-way data binding: Angular provides a powerful data binding mechanism that enables
ANGULAR automatic synchronization of data between the model (component) and the view (HTML). Changes
in the model are reflected in the view and vice versa, without manual DOM manipulation.
What is Angular? ➢ Dependency injection: Angular has a built-in dependency injection system that facilitates the
management of dependencies between different parts of an application. It helps improve code
Angular is a popular open-source web application framework that is primarily used to build dynamic single- quality, reusability, and testability by promoting loose coupling and modular design.
page applications (SPAs). It is developed and maintained by Google. Angular allows developers to build ➢ Templating: Angular offers a declarative templating language that allows developers to define
client-side applications using TypeScript, a superset of JavaScript. dynamic and interactive views. Templates in Angular combine HTML with additional syntax and
directives to render data and respond to user interactions.
Some key features of Angular include:
➢ Routing: Angular provides a powerful routing module that enables developers to define and handle
application navigation. It allows the creation of multiple views and supports features like lazy
➢ Component-based architecture: Angular follows a component-based approach, where the
loading, route guards, and parameter passing.
application is divided into reusable and self-contained components. Each component consists of
➢ Forms handling: Angular provides robust support for building and validating forms. It offers two
HTML templates, TypeScript code, and CSS styles, which work together to define the component's
approaches: template-driven forms, where the majority of the form logic is defined in the template
behavior and appearance.
itself, and reactive forms, where the form logic is defined programmatically using reactive
➢ Two-way data binding: Angular provides a powerful data binding mechanism that allows automatic
programming.
synchronization of data between the model (component) and the view (HTML). This means that any
➢ Cross-platform development: Angular supports cross-platform development, allowing developers
changes in the model will reflect in the view and vice versa, without the need for manual DOM
to build applications that run on various platforms, including web browsers, desktop, and mobile. It
manipulation.
achieves this through frameworks like Angular Universal for server-side rendering and Angular
➢ Dependency injection: Angular has built-in dependency injection, which helps manage the
Mobile Toolkit for mobile app development.
dependencies between different parts of an application. It simplifies the creation and management
➢ Testing support: Angular has a comprehensive testing ecosystem that includes tools and libraries
of objects and promotes modularity, testability, and reusability.
for writing unit tests, integration tests, and end-to-end tests. It promotes test-driven development
➢ Routing: Angular includes a robust router module that enables developers to define and handle
(TDD) and provides utilities for mocking and simulating dependencies.
application navigation. It allows the creation of multiple views and provides features like lazy
➢ Performance optimization: Angular offers various features to optimize application performance. It
loading, route guards, and parameter passing.
includes features like lazy loading, Ahead-of-Time (AOT) compilation, tree shaking, and code
➢ Form handling: Angular provides powerful form handling capabilities with features like form
minification, which help reduce the bundle size and improve load times.
validation, error handling, and data binding. It supports both template-driven forms (where most of
➢ Extensibility: Angular is highly extensible and allows developers to add custom functionality
the form logic is defined in the template) and reactive forms (where the form logic is defined
through directives, pipes, and services. It also has a rich ecosystem of third-party libraries and
programmatically using reactive programming).
packages that can be integrated into Angular applications.
➢ Testing support: Angular has a comprehensive testing framework that allows developers to write
unit tests, integration tests, and end-to-end tests for their applications. This helps ensure the quality
These features make Angular a powerful and versatile framework for building modern, scalable, and
and reliability of the codebase.
maintainable web applications.
Angular is widely used by developers for building complex and scalable web applications. It has a large
ecosystem of libraries, tools, and community support, making it a popular choice for web development.
Angular Application Setup:
➢ Open your favorite code editor and start modifying the files in the src directory to build your To create a module, you can use the Angular CLI command:
Angular application. The main file is src/app/app.component.ts, which contains the root component
ng generate module module-name
for your application.
This command generates the necessary files for the module and updates the relevant configuration.
From this point, you can begin developing your Angular application by creating components, services, and
other Angular constructs. You can use the Angular CLI to generate components, services, modules, and
more, which will automatically create the necessary files and update the configuration.
Modules can also import and export other modules, allowing components, services, and other resources to
For more information on how to develop Angular applications, refer to the Angular documentation:
be shared across modules. This promotes modularity and code reuse.
https://angular.io/docs
Additionally, Angular has a root module called the AppModule, which serves as the entry point of the In Angular, the template is a key part of a component and is responsible for defining the structure and
application. It imports and configures other modules and specifies the bootstrap component that is loaded layout of the component's view. The template consists of HTML markup combined with Angular-specific
when the application starts. syntax and features. Here are the elements commonly used in an Angular template:
Components and modules work together to structure and organize an Angular application. Components ➢ Interpolation ({{ }}): Interpolation allows you to embed dynamic values from the component's data
represent individual UI elements, while modules provide a way to group and manage related components into the template. You can use double curly braces {{ }} to surround an expression that will be
and other code. This modular approach helps improve maintainability, reusability, and testability of the evaluated and displayed in the rendered view.
application. ➢ Property Binding ([]): Property binding allows you to bind a component's property to an element's
property or attribute in the template. You use square brackets [] to bind a component property to
Executing Angular Application: an element property or attribute.
➢ Event Binding (()): Event binding allows you to respond to user actions such as button clicks, mouse
To execute an Angular application, you need to follow these steps: events, or form submissions. You use parentheses () to bind a component method to an element's
event.
➢ Make sure you have set up your Angular application and installed the necessary dependencies as ➢ Directives: Angular provides built-in and custom directives that allow you to manipulate the
mentioned in the previous response. structure and behavior of the DOM elements. Directives can be applied to elements as attributes,
➢ Open a terminal or command prompt and navigate to the root directory of your Angular classes, or as structural directives that alter the layout of the DOM.
application. ➢ Structural Directives (*ngIf, *ngFor, *ngSwitch): Structural directives allow you to conditionally add
➢ Run the following command to start the development server: or remove elements from the DOM, iterate over a collection to generate multiple elements, or
switch between different elements based on a condition. They are denoted by an asterisk * prefix.
ng serve
➢ Template Reference Variables (#): Template reference variables allow you to capture references to
HTML elements or Angular directives within the template. You can use these variables to interact
This command will compile your Angular application and launch a development server. The server will
with the elements or directives in your component's logic.
monitor your code for changes, recompile the application as needed, and automatically reload it in the
➢ Two-Way Data Binding ([(ngModel)]): Two-way data binding combines property binding and event
browser.
binding to create a bidirectional data flow between the component and the template. It allows you
➢ Open a web browser and go to http://localhost:4200/ (or the specific URL shown in the terminal) to to update the component's property and reflect the changes in the template automatically.
view your Angular application. The development server provides a live preview of your application, ➢ Pipes (|): Pipes allow you to transform and format data before displaying it in the template. Angular
and any changes you make to the code will be reflected instantly in the browser. provides several built-in pipes such as date, uppercase, lowercase, and you can also create custom
➢ Start interacting with your Angular application in the browser and test its functionality. You can pipes.
navigate through the application, click on buttons or links, fill out forms, and observe how the ➢ Template Expression Operators: Angular templates support various operators for performing
application responds. operations and evaluations within expressions. These include arithmetic operators (+, -, *, /),
➢ While the development server is running, you can continue making changes to your code, and the comparison operators (==, !=, >, <), logical operators (&&, ||), and more.
server will automatically rebuild and reload the application with the updated changes.
These are some of the key elements you'll commonly find in an Angular template. By utilizing these
➢ To stop the development server, go back to the terminal or command prompt where it is running
elements, you can create dynamic and interactive views that respond to user input and reflect changes in
and press Ctrl + C to terminate the server.
the component's data.
That's it! You have successfully executed your Angular application using the development server. During
development, this is the preferred way to run and test your application as it provides a smooth Change Detection:
development experience with automatic reloading. For production deployment, you would typically build
the application using the Angular CLI and deploy the generated output to a web server. Change detection is a core concept in Angular that tracks changes to the application's data and updates the
corresponding views. It ensures that the user interface reflects the most up-to-date state of the
Elements of Template:
application. Angular employs a mechanism called "change detection" to efficiently identify and propagate ngIf is used to conditionally add or remove elements from the DOM based on a given condition. It
changes throughout the application. evaluates an expression and only renders the associated template if the expression evaluates to a truthy
value. If the expression is falsy, the template is removed from the DOM.
Here's how change detection works in Angular:
Example:
➢ Change detection starts at the root component of the application and traverses the component
tree, visiting each component. <div *ngIf="showElement">
➢ During change detection, Angular compares the current state of a component's data with its
previous state to detect changes. It does this by performing a deep check of the component's This element is conditionally rendered.
properties, including objects and arrays.
➢ If Angular detects changes in a component's data, it updates the associated view to reflect the new </div>
values. This process involves updating the DOM, rerendering the templates, and updating any
In the example, the <div> element will only be rendered if the showElement property in the component
bindings or directives applied to the elements.
evaluates to true.
➢ After updating a component's view, Angular checks if any child components have been affected by
the changes. If so, it recursively performs change detection on those components as well, ensuring ➢ ngFor:
that changes propagate throughout the component tree.
ngFor is used for looping over a collection of items and generating multiple elements in the DOM. It
Angular's change detection algorithm is optimized to be efficient and performant. It uses a technique called iterates over an array or an iterable object and repeats a section of HTML for each item in the collection.
"unidirectional data flow," where changes flow from parent components to child components in a
hierarchical manner. Example:
In addition to the default change detection strategy, Angular provides two alternative change detection <ul>
strategies:
<li *ngFor="let item of items">
➢ OnPush Change Detection: With this strategy, change detection is triggered only when the
component's input properties change or when an event occurs within the component. It allows for {{ item }}
better performance by reducing unnecessary checks.
➢ Manual Change Detection: In this strategy, change detection is entirely controlled by the developer. </li>
Angular does not automatically perform change detection. Instead, developers manually trigger
change detection when they explicitly call the detectChanges() method. </ul>
In the example, each item in the items array is rendered as a <li> element within the <ul> list.
By understanding change detection in Angular, developers can optimize their application's performance,
minimize unnecessary checks, and ensure that the UI is always in sync with the underlying data.
➢ ngSwitch:
Structural Directives - ngIf, ngFor, ngSwitch: ngSwitch is used for conditional rendering based on multiple values. It acts as a switch statement to
determine which template to render based on the value of a given expression.
Structural directives are a type of directive in Angular that alter the structure of the DOM (Document
Object Model) by adding or removing elements based on certain conditions. Angular provides several built- Example:
in structural directives, including ngIf, ngFor, and ngSwitch. Here's an overview of these directives:
<div [ngSwitch]="color">
➢ ngIf:
<p *ngSwitchCase="'red'">Red color is selected</p>
<p *ngSwitchCase="'blue'">Blue color is selected</p> constructor(private templateRef: TemplateRef<any>, private viewContainerRef: ViewContainerRef)
{}
<p *ngSwitchCase="'green'">Green color is selected</p>
}
<p *ngSwitchDefault>No color is selected</p>
➢ In the directive class, inject TemplateRef and ViewContainerRef into the constructor. These
</div> parameters allow you to access the template and manipulate the view container.
In the example, the <p> element within each ngSwitchCase block will be rendered based on the value of TemplateRef represents the template associated with the element where the directive is applied.
the color property in the component. If no case matches, the <p> element within ngSwitchDefault will be
rendered. ViewContainerRef represents the container that holds the view of the element where the directive is
applied.
These structural directives provide powerful ways to conditionally render elements, loop over collections,
and perform switch-like logic in Angular templates. They enable dynamic and flexible rendering of the DOM ➢ Implement the desired behavior of your custom structural directive. For example, you can
based on the application's data and conditions. conditionally add or remove elements from the DOM based on a specific condition. You can use
methods provided by TemplateRef and ViewContainerRef to manipulate the DOM structure:
Custom Structural Directive: import { Directive, TemplateRef, ViewContainerRef } from '@angular/core';
In Angular, you can create custom structural directives to extend the functionality of the built-in directives @Directive({
or introduce new structural directives specific to your application's requirements. Custom structural selector: '[appDirectiveName]'
directives allow you to manipulate the DOM structure based on custom conditions. Here's how you can })
create a custom structural directive in Angular: export class DirectiveNameDirective {
constructor(private templateRef: TemplateRef<any>, private viewContainerRef:
➢ Create a new directive using the Angular CLI command: ViewContainerRef) { }
ng generate directive directive-name
// Example behavior: Conditionally render the template based on a boolean value
This command generates the necessary files for the directive, including a TypeScript file and a test file.
@Input() set appDirectiveName(condition: boolean) {
if (condition) {
➢ Open the generated TypeScript file (e.g., directive-name.directive.ts) and import the necessary
this.viewContainerRef.createEmbeddedView(this.templateRef);
modules and decorators:
} else {
import { Directive, TemplateRef, ViewContainerRef } from '@angular/core';
this.viewContainerRef.clear();
➢ Decorate the directive class with the @Directive decorator, providing a selector to use the directive
}
in the template:
}
@Directive({ }
➢ Use your custom structural directive in the template by applying it to the desired element and
selector: '[appDirectiveName]' providing the necessary inputs:
<div *appDirectiveName="myCondition">...</div>
})
In the example, the appDirectiveName directive is applied to the <div> element, and the myCondition
export class DirectiveNameDirective { property in the component is used to control the rendering behavior of the directive.
➢ Register the custom structural directive in an Angular module by importing and declaring it in the Example:
module's @NgModule decorator:
import { DirectiveNameDirective } from './directive-name.directive'; <div [ngClass]="{'active': isActive, 'highlight': shouldHighlight}">
That's it! You have created a custom structural directive in Angular. Now, when you use your custom Both ngStyle and ngClass directives support multiple conditions and complex expressions for dynamic
directive in the template, it will modify the DOM structure based on the specified conditions and logic in styling and class application. You can combine them with other directives, event bindings, or template
the directive implementation. expressions to create rich and interactive user interfaces.
Attribute Directives - ngStyle, ngClass: Note: Remember to import the necessary Angular modules in your component's module (@NgModule) for
these directives to work properly. For ngStyle, you need to import the CommonModule, and for ngClass,
In Angular, attribute directives allow you to manipulate the behavior and appearance of HTML elements by you need to import the CommonModule or BrowserAnimationsModule (if using animations).
modifying their attributes. Angular provides several built-in attribute directives, including ngStyle and
ngClass, which are commonly used to dynamically apply styles and classes to elements based on conditions Custom Attribute Directive:
or data values. Here's an overview of these attribute directives:
In Angular, you can create custom attribute directives to modify the behavior or appearance of HTML
➢ ngStyle: elements by manipulating their attributes. Custom attribute directives allow you to define custom logic
that is applied when the directive is used on an element. Here's how you can create a custom attribute
The ngStyle directive allows you to dynamically apply inline styles to HTML elements based on properties of
directive in Angular:
the component. You can bind an object literal or a component property to the ngStyle directive.
➢ Create a new directive using the Angular CLI command:
Example:
ng generate directive directive-name
<div [ngStyle]="{'color': textColor, 'font-size': fontSize + 'px'}">
This command generates the necessary files for the directive, including a TypeScript file and a test file.
This text will be styled dynamically.
➢ Open the generated TypeScript file (e.g., directive-name.directive.ts) and import the necessary
</div>
modules and decorators:
In the example, the ngStyle directive is used to apply the color and font-size styles to the <div> element import { Directive, ElementRef, Renderer2 } from '@angular/core';
based on the component's textColor and fontSize properties. ➢ Decorate the directive class with the @Directive decorator, providing a selector to use the directive
in the template:
➢ ngClass: @Directive({
selector: '[appDirectiveName]'
The ngClass directive allows you to conditionally apply CSS classes to HTML elements. You can bind an })
object literal, a component property that returns an object, or an array of CSS class names to the ngClass export class DirectiveNameDirective {
directive. constructor(private el: ElementRef, private renderer: Renderer2) { }
}
➢ In the directive class, inject ElementRef and Renderer2 into the constructor. These parameters That's it! You have created a custom attribute directive in Angular. Now, when you use your custom
allow you to access and manipulate the element on which the directive is applied. directive in the template, it will modify the behavior or appearance of the element to which it is applied
based on the logic defined in the directive implementation.
ElementRef provides access to the underlying native element.
Property Binding:
Renderer2 provides methods to manipulate the element's attributes and styles.
Property binding is a feature in Angular that allows you to set the value of a property or attribute of an
➢ Implement the desired behavior of your custom attribute directive. For example, you can add or
HTML element dynamically based on the data or expressions in your component. It establishes a
remove attributes, modify styles, or attach event listeners:
unidirectional flow of data from the component to the template. With property binding, you can update
import { Directive, ElementRef, Renderer2 } from '@angular/core';
properties, such as value, disabled, src, href, and many more, of HTML elements dynamically. Here's how
you can use property binding in Angular:
@Directive({
selector: '[appDirectiveName]' ➢ Surround the attribute or property value in square brackets ([]) within the template and assign it to
}) a property or expression in the component.
export class DirectiveNameDirective { <input [value]="myProperty">
constructor(private el: ElementRef, private renderer: Renderer2) {
this.renderer.setStyle(this.el.nativeElement, 'color', 'red'); In the example, the value of the myProperty property in the component is bound to the value property of
this.renderer.addClass(this.el.nativeElement, 'custom-class'); the <input> element. Any changes to myProperty will be reflected in the input field.
}
} ➢ You can also bind to attributes other than the element's properties. Use attribute binding by
prefixing the attribute name with attr. and bind it to a component property or expression.
In the example, the appDirectiveName directive sets the color of the element to red and adds the custom- <a [attr.href]="urlProperty">Go to Link</a>
class CSS class to the element.
In this case, the value of the urlProperty property in the component is bound to the href attribute of the
➢ Use your custom attribute directive in the template by applying it to the desired element: <a> element.
<div appDirectiveName>
This element is affected by the custom directive. ➢ Property binding can also be used with built-in directives like ngStyle and ngClass. You can bind
</div> properties to apply dynamic styles or classes to elements.
<div [ngStyle]="{ 'color': textColor, 'font-size': fontSize + 'px' }"></div>
In the example, the appDirectiveName directive is applied to the <div> element. <div [ngClass]="{ 'active': isActive, 'highlight': shouldHighlight }"></div>
➢ Register the custom attribute directive in an Angular module by importing and declaring it in the In the examples, the textColor, fontSize, isActive, and shouldHighlight properties are bound to the styles
module's @NgModule decorator: and classes applied to the <div> elements.
import { DirectiveNameDirective } from './directive-name.directive';
➢ You can bind to events as well using event binding syntax. Enclose the event name in parentheses
@NgModule({ and assign it to a method in the component.
declarations: [DirectiveNameDirective], <button (click)="handleClick()">Click Me</button>
// ...
}) In this case, the click event of the <button> element is bound to the handleClick() method in the
export class AppModule { } component.
Property binding allows you to establish dynamic relationships between the component and the template,
enabling you to update and manipulate the properties and attributes of HTML elements based on
component data or expressions. It is a powerful tool for creating dynamic and interactive user interfaces in on the data and expressions in your component, enabling you to create more flexible and interactive
Angular. templates in Angular.
Attribute binding is a feature in Angular that allows you to dynamically set the value of an HTML element's Style Binding
attribute based on the data or expressions in your component. Unlike property binding, attribute binding
works with HTML attributes that do not have corresponding properties in the DOM API. Attribute binding Style binding is a feature in Angular that allows you to dynamically set CSS styles of HTML elements based
uses square brackets ([]) to bind a component property or expression to an attribute value. Here's how you on the data or expressions in your component. It provides a way to apply dynamic styles to elements, such
can use attribute binding in Angular: as changing colors, font sizes, visibility, and more. Style binding uses square brackets ([]) to bind a
component property or expression to a style property. Here's how you can use style binding in Angular:
➢ Surround the attribute name in square brackets ([]) within the template and assign it to a property
or expression in the component. ➢ Surround the style property in square brackets ([]) within the template and assign it to a property or
<div [attr.data-id]="itemId"></div> expression in the component.
<div [style.color]="textColor"></div>
In the example, the value of the itemId property in the component is bound to the data-id attribute of the
<div> element. In the example, the textColor property in the component is bound to the color style property of the <div>
element. The color of the <div> will be dynamically updated based on the value of textColor.
➢ You can also use attribute binding to dynamically set standard HTML attributes like disabled,
readonly, placeholder, etc. ➢ You can also use style binding to apply multiple styles by binding to an object literal containing style
<input [attr.disabled]="isDisabled"> properties and their values.
<div [style]="{ 'color': textColor, 'font-size': fontSize + 'px' }"></div>
In this case, the isDisabled property in the component is bound to the disabled attribute of the <input>
element. If isDisabled is true, the input will be disabled; otherwise, it will be enabled. In this case, the textColor and fontSize properties in the component are bound to the color and font-size
styles of the <div> element, respectively.
➢ Attribute binding can be combined with other bindings, such as property binding and event binding,
to create more dynamic interactions in your templates. ➢ Style binding can be combined with other bindings, such as attribute binding and event binding, to
<button [attr.data-action]="action" (click)="handleClick()">Click Me</button> create more dynamic and interactive styling in your templates.
In this example, the action property in the component is bound to the data-action attribute of the <button> Event Binding:
element, and the handleClick() method is bound to the click event of the button.
Event binding is a feature in Angular that allows you to respond to user interactions, such as button clicks,
➢ Attribute binding can also be used with built-in directives like ngClass and ngStyle to dynamically mouse movements, and key presses, by executing methods in your component. It establishes a connection
apply classes or styles based on component properties or expressions. between the template and the component, enabling you to handle user actions. Event binding uses
<div [ngClass]="{ 'active': isActive, 'highlight': shouldHighlight }"></div> parentheses (()) to bind an event of an HTML element to a method in the component. Here's how you can
<div [ngStyle]="{ 'color': textColor, 'font-size': fontSize + 'px' }"></div> use event binding in Angular:
In these examples, the isActive, shouldHighlight, textColor, and fontSize properties are bound to the ➢ Enclose the event name in parentheses (()) within the template and assign it to a method in the
attribute values used by ngClass and ngStyle directives. component.
<button (click)="handleClick()">Click Me</button>
Attribute binding allows you to set and manipulate HTML attributes that may not have corresponding
properties in the DOM API. It provides a way to dynamically control the attributes of HTML elements based In the example, the click event of the <button> element is bound to the handleClick() method in the
component. When the button is clicked, the method will be executed.
➢ You can also pass event objects or data to the method by using the $event keyword. CurrencyPipe:
<input (keyup)="handleKeyUp($event)">
The CurrencyPipe is used for formatting currency values with the specified currency code and symbol.
In this case, the keyup event of the <input> element is bound to the handleKeyUp() method in the
component, passing the event object to the method. Example:
➢ Event binding can be used with various events, such as click, keyup, mouseover, submit, and many <p>{{ amount | currency: 'USD' }}</p>
more, to capture and respond to user interactions in your application.
In this example, the amount property is formatted using the CurrencyPipe with the 'USD' currency code,
Both style binding and event binding provide powerful ways to create dynamic and interactive user which displays the value with the USD currency symbol.
interfaces in Angular. Style binding allows you to apply dynamic styles to elements based on component
data or expressions, while event binding enables you to respond to user interactions by executing methods PercentPipe:
in your component. These features together help you create engaging and responsive applications.
The PercentPipe is used for formatting numbers as percentages.
Angular provides a set of built-in pipes that you can use to transform and format data in your templates. <p>{{ discount | percent }}</p>
Pipes are simple functions that accept an input value and optional parameters, and they return a
transformed value. Here are some commonly used built-in pipes in Angular: In this example, the discount property is formatted using the PercentPipe, which displays the value as a
percentage.
DatePipe:
SlicePipe:
The DatePipe is used for formatting dates. It supports various date formats and options for displaying dates
and times. The SlicePipe is used for slicing arrays or strings and returning a subset of the original data.
Example: Example:
In this example, the currentDate property is formatted using the DatePipe with the 'short' format, which <li *ngFor="let item of items | slice:0:3">{{ item }}</li>
displays the date and time in a short format.
</ul>
DecimalPipe:
In this example, the SlicePipe is used within an ngFor directive to display the first three items from the
The DecimalPipe is used for formatting numbers with decimal places, thousands separators, and currency items array.
symbols.
These are just a few examples of the built-in pipes available in Angular. There are many more, including
Example: UpperCasePipe, LowerCasePipe, AsyncPipe, and JsonPipe, among others. Pipes provide a convenient way
to transform and format data in your templates without modifying the underlying component properties.
<p>{{ price | number: '1.2-2' }}</p> You can also chain multiple pipes together to perform complex data transformations.
In this example, the price property is formatted using the DecimalPipe with the '1.2-2' format, which
Passing Parameters to Pipes:
displays the number with two decimal places and optional thousands separators.
In Angular, you can pass parameters to built-in pipes and custom pipes to customize their behavior. This return transformedValue;
allows you to apply specific transformations or formatting based on dynamic values. Here's how you can
pass parameters to pipes: }
Built-in Pipes: }
When using a built-in pipe, you can pass parameters by separating them with colons (:) within the pipe Step 3: Use the custom pipe in the template and pass the parameter(s) as arguments.
syntax.
<p>{{ someValue | myCustomPipe: param1: param2 }}</p>
Example:
In this example, the someValue property is transformed using the myCustomPipe, and the param1 and
<p>{{ currentDate | date: 'fullDate' }}</p> param2 values are passed as parameters to the pipe.
In this example, the date pipe is used with the 'fullDate' parameter, which formats the currentDate Note: You can have multiple parameters in a custom pipe by separating them with colons (:) within the
property as a full date. pipe syntax.
Custom Pipes: By passing parameters to pipes, you can customize their behavior and perform specific transformations or
formatting based on dynamic values. This flexibility allows you to create reusable and adaptable pipes that
When using a custom pipe, you need to define the parameter(s) within the pipe implementation and pass can be used in different scenarios within your Angular application.
the value(s) when using the pipe in the template.
Nested Components Basics:
Step 1: Create a custom pipe using the Angular CLI:
In Angular, nested components refer to the concept of creating a component hierarchy, where one
ng generate pipe myCustomPipe component is used within another component. This allows for better code organization, reusability, and
separation of concerns. To understand nested components in Angular, let's go through the basics:
Step 2: Open the generated pipe file (e.g., my-custom-pipe.pipe.ts) and define the parameter(s) in the
transform method. ➢ Component Creation:
import { Pipe, PipeTransform } from '@angular/core'; To create a new component in Angular, you can use the Angular CLI (Command Line Interface) by running
the command ng generate component component-name.
This command will generate the necessary files for the component, including a TypeScript file (.ts), an
@Pipe({
HTML template file (.html), a CSS file (.css), and a spec file (.spec.ts) for testing.
name: 'myCustomPipe'
➢ Parent-Child Relationship:
})
In Angular, components can have a parent-child relationship, where one component acts as the parent and
another as the child.
export class MyCustomPipe implements PipeTransform {
The parent component can contain the child component in its template and provide data to the child
transform(value: any, param1: any, param2: any): any {
component.
// Custom transformation logic using the value and parameters
➢ Component Communication:
To communicate between parent and child components, Angular provides two mechanisms: input Passing data from Container Component to Child Component:
properties and output events.
To pass data from a container component (parent) to a child component in Angular, you can use input
Input properties allow the parent component to pass data to the child component. The child component properties. Input properties allow the parent component to bind data to the child component. Here's how
uses the @Input decorator to define an input property. you can do it:
Output events allow the child component to emit events to the parent component. The child component ➢ Define an Input Property in the Child Component:
uses the @Output decorator along with an EventEmitter to define an output event.
In the child component's TypeScript file, declare an input property using the @Input decorator. This
➢ Using Nested Components: property will receive the data from the parent component.
To use a nested component, you need to include its selector in the template of the parent component. For example, in the child component's TypeScript file:
For example, if you have a parent component called ParentComponent and a child component called import { Component, Input } from '@angular/core';
ChildComponent, you can include the child component in the parent's template like this: <app-child></app-
child>, assuming the selector of the child component is app-child. @Component({
To pass data from the parent component to the child component, you can use input properties. templateUrl: './child.component.html',
In the parent component's template, you can bind a property to the child component's input property styleUrls: ['./child.component.css']
using square brackets ([]).
})
For example, if the child component has an input property called data, you can pass data from the parent
component like this: <app-child [data]="parentData"></app-child>, where parentData is a property in the export class ChildComponent {
parent component.
@Input() data: string; // Define an input property called 'data'
➢ Emitting Events from Child Components:
}
To emit events from the child component to the parent component, you can use output events.
➢ Bind the Property in the Parent Component's Template:
In the child component's TypeScript file, you define an output event using the @Output decorator and an
EventEmitter. Then, you can emit the event using the emit() method. In the parent component's HTML template, bind the desired property to the child component's input
property using square brackets ([]).
In the parent component's template, you can listen to the child component's output event using
parentheses (()). For example, in the parent component's template:
For example, if the child component has an output event called childEvent, you can listen to it in the parent <app-child [data]="parentData"></app-child>
component like this: <app-child (childEvent)="handleEvent($event)"></app-child>, where handleEvent() is
In this example, parentData is a property in the parent component that you want to pass to the child
a method in the parent component.
component's data input property.
By using these techniques, you can create a hierarchy of nested components in Angular, allowing for a
➢ Pass the Data from the Parent Component:
modular and reusable application structure.
In the parent component's TypeScript file, define the parentData property and assign the desired value to In the child component's TypeScript file, declare an output event using the @Output decorator and an
it. instance of EventEmitter.
For example, in the parent component's TypeScript file: For example, in the child component's TypeScript file:
import { Component } from '@angular/core'; import { Component, Output, EventEmitter } from '@angular/core';
@Component({ @Component({
}) })
parentData: string = 'Hello from parent component!'; @Output() childEvent: EventEmitter<string> = new EventEmitter<string>(); // Define an output event
called 'childEvent'
}
sendDataToParent() {
➢ Access the Data in the Child Component:
const dataToSend = 'Hello from child component!';
In the child component, you can access the data received from the parent component via the input
property (data in the example). this.childEvent.emit(dataToSend); // Emit the event with the data
<p>{{ data }}</p> <!-- Display the value of the 'data' property --> }
By following these steps, you can pass data from a container component to a child component in Angular ➢ Emit the Event from the Child Component:
using input properties. The child component will receive the data and can use it as needed in its template
or logic. In the child component's TypeScript file, create a method that will emit the output event when triggered.
Use the emit() method on the childEvent EventEmitter instance to emit the event and pass the desired
Passing data from Child Component to Container Component: data.
To pass data from a child component to a container component (parent) in Angular, you can use output For example, in the child component's TypeScript file:
events. Output events allow the child component to emit events that the parent component can listen to
sendDataToParent() {
and react accordingly. Here's how you can do it:
const dataToSend = 'Hello from child component!';
➢ Define an Output Event in the Child Component:
this.childEvent.emit(dataToSend); // Emit the event with the data By following these steps, you can pass data from a child component to a container component in Angular
using output events. The child component emits an event with the desired data, and the container
} component listens to the event and handles it accordingly in the event handler method.
By default, Angular uses the Emulated view encapsulation mode. However, you can specify a different
})
mode for a component by setting the encapsulation property in the component's metadata.
export class ContainerComponent {
For example, to use the Native view encapsulation mode, you would specify it in the component's
handleChildEvent(data: string) { metadata:
console.log('Received data from child component:', data); import { Component, ViewEncapsulation } from '@angular/core';
} selector: 'app-example',
} templateUrl: './example.component.html',
styleUrls: ['./example.component.css'], In Angular, components have a lifecycle that consists of various stages or hooks that are executed at
different points during the component's creation, rendering, and destruction. These lifecycle hooks allow
encapsulation: ViewEncapsulation.Native you to perform actions at specific moments in the component's lifecycle. Here are the main lifecycle hooks
available in Angular:
})
ngOnChanges:
export class ExampleComponent {
This hook is called when one or more of the component's input properties change.
// Component logic
It receives a SimpleChanges object that contains information about the previous and current values of the
} input properties.
With view encapsulation, component styles defined in the component's CSS file or inline styles are scoped ngOnChanges(changes: SimpleChanges) {
to the component's template.
// Perform actions based on input property changes
In the default Emulated mode, Angular adds a unique attribute to the component's host element, and the
component's styles are transformed with the attribute selector to apply only to that component. }
In the Native mode, the component's styles are encapsulated within the Shadow DOM subtree, and they ngOnInit:
don't leak out or affect other parts of the application.
This hook is called once, after the component and its child components have been initialized and their
Using view encapsulation with Shadow DOM in Angular provides several benefits, including: input properties have been set.
Style scoping: Component styles are scoped to the component's template, preventing unintended style It is commonly used to initialize data, make API calls, or perform other setup tasks.
conflicts with other components.
Example:
Code organization: Styles and template structure are encapsulated within the component, improving code
modularity and maintainability. ngOnInit() {
Reusability: Components with encapsulated styles can be easily reused without worrying about style // Perform initialization tasks
interference.
}
Isolation: DOM elements and behavior within the component are isolated, minimizing unintended side
effects on other parts of the application. ngDoCheck:
Note that while Angular supports Shadow DOM through the Native view encapsulation mode, it also This hook is called during every change detection cycle of the component.
provides a robust emulation of Shadow DOM with the default Emulated mode, allowing for consistent
behavior across browsers. It is used to detect and respond to changes that Angular cannot detect automatically, such as changes to
properties of an object or changes in complex data structures.
Component Life Cycle:
Example:
ngDoCheck() { Example:
ngAfterContentInit: }
This hook is called after the component's content (e.g., child components, projected content) has been ngAfterViewChecked:
initialized.
This hook is called after the component's view has been checked for changes.
It is commonly used to interact with the component's content or child components after they have been
created. It is called after every change detection cycle and can be used to perform additional actions based on the
component's view.
Example:
Example:
ngAfterContentInit() {
ngAfterViewChecked() {
// Perform actions after content initialization
// Perform actions after view has been checked
}
}
ngAfterContentChecked:
ngOnDestroy:
This hook is called after the component's content has been checked for changes.
This hook is called just before the component is destroyed and removed from the DOM.
It is called after every change detection cycle and can be used to perform additional actions based on the
component's content. It is commonly used to clean up resources, unsubscribe from observables, or perform other cleanup tasks.
Example: Example:
ngAfterContentChecked() { ngOnDestroy() {
// Perform actions after content has been checked // Perform cleanup tasks before component destruction
} }
ngAfterViewInit: These lifecycle hooks allow you to control the behavior and perform actions at different stages of a
component's lifecycle. By leveraging these hooks, you can initialize data, interact with the DOM, handle
This hook is called after the component's view (DOM) has been initialized. changes, and clean up resources when necessary.
It is commonly used to interact with the component's view or perform actions that require access to the Template Driven Forms: In Angular, Template-driven forms provide an approach to creating forms
rendered DOM. using Angular's template syntax. With Template-driven forms, the form controls and validation logic are
primarily defined in the component's template rather than in the component class. Here's an overview of </div>
how to use Template-driven forms in Angular:
<div>
➢ Import FormsModule:
<label for="email">Email:</label>
To use Template-driven forms, you need to import the FormsModule from @angular/forms in your
application module (e.g., app.module.ts). <input type="email" id="email" name="email" [(ngModel)]="user.email" required>
Example: </div>
@NgModule({ </form>
FormsModule Add an event handler method in the component class to handle the form submission. In the example
above, we bind the (ngSubmit) event of the <form> element to the onSubmit() method.
],
Example:
// Other module configurations
export class MyComponent {
})
user: any = {};
export class AppModule { }
onSubmit() {
Create a Form in the Template:
// Form submission logic
In the component's template, define the form using the <form> element and add form controls using
various input elements such as <input>, <select>, and <textarea>. }
Use the ngModel directive to bind form controls to properties in the component class for two-way data }
binding.
Form Validation:
Example:
Use HTML5 validation attributes such as required, minlength, maxlength, etc., to specify validation rules for
<form (ngSubmit)="onSubmit()"> form controls.
<div> Angular automatically updates the form's validity and provides visual feedback such as error messages
based on these attributes.
<label for="name">Name:</label>
Example:
<input type="text" id="name" name="name" [(ngModel)]="user.name" required>
<div>
<label for="password">Password:</label> // Other module configurations
</div> Define a FormGroup instance to represent the entire form and create FormControl instances for each form
control.
</div>
Assign the form controls to the form group using key-value pairs.
Template-driven forms provide a simpler approach for creating forms in Angular, especially for simple and
straightforward forms. However, they may have limitations when it comes to complex form scenarios and Example:
custom form validation. For more advanced form requirements, Reactive Forms offer more flexibility and
control. import { Component } from '@angular/core';
Model Driven Forms or Reactive Forms: import { FormGroup, FormControl, Validators } from '@angular/forms';
@Component({
In Angular, Reactive Forms (also known as Model-driven Forms) provide a more flexible and powerful
approach for building forms compared to Template-driven forms. Reactive Forms are based on the Reactive
selector: 'app-my-component',
Programming paradigm and allow you to define form controls and validation logic programmatically in the
component class. Here's an overview of how to use Reactive Forms in Angular: templateUrl: './my-component.component.html',
To use Reactive Forms, you need to import the ReactiveFormsModule from @angular/forms in your })
application module (e.g., app.module.ts).
export class MyComponent {
Example:
myForm: FormGroup;
import { ReactiveFormsModule } from '@angular/forms';
constructor() {
@NgModule({
this.myForm = new FormGroup({
imports: [
name: new FormControl('', Validators.required),
ReactiveFormsModule
email: new FormControl('', [Validators.required, Validators.email]),
],
password: new FormControl('', [Validators.required, Validators.minLength(8)])
}); <button type="submit" [disabled]="myForm.invalid">Submit</button>
} </form>
// Form submission logic Use the Validators class from @angular/forms to define validation rules for form controls.
} You can access the form controls in the component class and check their validity, errors, and other
properties.
}
Example:
➢ Link Form Controls to the Template:
onSubmit() {
In the component's template, bind the form controls to the corresponding input elements using the
formControlName directive. if (this.myForm.valid) {
<label for="name">Name:</label> }
<label for="email">Email:</label> }
<div> }
<input type="password" id="password" name="password" formControlName="password"> Reactive Forms provide advanced features such as dynamic form control manipulation, custom validators,
cross-field validation, and more. They offer greater control and flexibility compared to Template-driven.
</div>
Custom Validators in Reactive Forms: const myControl = new FormControl('', customValidator);
In Angular, you can create custom validators to implement custom validation logic for your Reactive Forms. // or
Custom validators are functions that take a form control as an input and return an object with validation
myControl.setValidators(customValidator);
errors if the validation fails, or null if the validation is successful. Here's how you can create custom
validators in Angular:
➢ Using the Custom Validator in Template and Component:
➢ Create a Custom Validator Function:
In the template, you can access the validation errors returned by the custom validator using the errors
property of the form control.
Define a function that takes a form control as an argument and returns an object with validation errors or
null.
In the component class, you can access the form control and check its validity, errors, and other properties.
The function should have the following signature: (control: AbstractControl): ValidationErrors | null.
Example:
Example:
<input type="text" id="myInput" name="myInput" formControlName="myControl">
import { AbstractControl, ValidationErrors } from '@angular/forms';
<div *ngIf="myControl.errors?.customError">Custom validation failed.</div>
function customValidator(control: AbstractControl): ValidationErrors | null {
By creating custom validators, you can implement your own validation rules and apply them to form
controls in your Reactive Forms. These validators can be used alongside built-in validators provided by
// Perform custom validation logic
Angular's Validators class, giving you the flexibility to enforce complex validation requirements for your
if (/* validation fails */) { forms.
} In Angular, you can also create custom validators for Template-driven forms. Custom validators in
Template-driven forms are functions that you can define in the component class and use in the template to
return null; // Validation successful perform custom validation logic. Here's how you can create custom validators in Template-driven forms:
➢ Register the Custom Validator: Define a function in the component class that takes a form control or an abstract control as an argument
and returns an object with validation errors if the validation fails, or null if the validation is successful.
You can register the custom validator function at the form control level or at the form group level,
depending on your requirements. The function should have the following signature: (control: AbstractControl): ValidationErrors | null.
To register the custom validator at the form control level, you can pass the validator function as the second Example:
argument to the FormControl constructor or use the setValidators() method to add it later.
import { AbstractControl, ValidationErrors } from '@angular/forms';
Example:
function customValidator(control: AbstractControl): ValidationErrors | null {
import { FormControl, Validators } from '@angular/forms';
// Perform custom validation logic
if (/* validation fails */) { the class or component is instantiated. This approach promotes modularity, testability, and reusability of
code.
return { customError: true };
In Angular, there are three main participants in the dependency injection process:
}
➢ Injectable Classes:
return null; // Validation successful
Injectable classes are classes that have dependencies and can be injected with the required dependencies.
}
To make a class injectable, you can decorate it with the @Injectable() decorator. This decorator marks the
➢ Use the Custom Validator in the Template: class as a provider of services or dependencies.
In the template, you can apply the custom validator by adding it to the ngModel directive of the form Example:
control using the validators property.
import { Injectable } from '@angular/core';
Example:
@Injectable()
<input type="text" id="myInput" name="myInput" [(ngModel)]="myModel" #myInput="ngModel"
[validators]="customValidator"> export class MyService {
You can access the validation errors returned by the custom validator using the errors property of the form ➢ Providers:
control.
Providers are responsible for creating and managing instances of injectable classes.
In the example above, we check if the customError validation error exists on the myInput form control and
display an error message if it does. In Angular, providers are typically defined at the module level or component level.
Note that the form control should have the ngModel directive and a reference variable Providers can be registered in the providers array of an Angular module or in the providers metadata
(#myInput="ngModel") for accessing the validation errors. property of a component.
Custom validators in Template-driven forms provide a way to implement custom validation logic directly in Example:
the template without the need for explicit form control creation in the component class. However, if you
have more complex validation requirements or need to perform validation logic in the component class, import { NgModule } from '@angular/core';
Reactive Forms with custom validators might be a better option.
import { MyService } from './my.service';
Dependency Injection (DI) is a core feature of the Angular framework that helps manage the dependencies providers: [MyService]
between different components and services. DI allows you to declare the dependencies of a class or
component in a way that the framework can automatically resolve and provide those dependencies when })
export class AppModule { } By utilizing dependency injection, you can easily manage the dependencies of your components and
services, decouple code modules, promote code reusability, and enable better testing and maintenance of
➢ Dependency Injection: your Angular applications.
Angular's DI system takes care of injecting dependencies into classes or components that declare their Services Basics:
dependencies.
In Angular, services are used to encapsulate and provide functionality that can be shared across multiple
To inject a dependency, you can declare a constructor parameter with the type of the dependency.
components. Services act as a centralized place to manage data, perform business logic, and interact with
external resources such as APIs or databases. Here are the basics of using services in Angular:
The Angular DI system will automatically resolve and provide an instance of the dependency when creating
an instance of the class.
➢ Creating a Service:
Example:
To create a service in Angular, you can generate a new service file using the Angular CLI command: ng
generate service my-service.
import { Component } from '@angular/core';
Alternatively, you can manually create a new TypeScript file for your service and define a class that
import { MyService } from './my.service';
provides the desired functionality.
@Component({
Example:
selector: 'app-my-component',
import { Injectable } from '@angular/core';
template: '...',
@Injectable({
providers: [MyService]
providedIn: 'root'
})
})
export class MyComponent {
export class MyService {
constructor(private myService: MyService) {
// Service functionality and data
// Use myService instance
}
}
➢ Providing the Service:
}
By default, Angular services are registered with the root injector, making them available to the entire
The Angular DI system uses hierarchical injection, meaning that dependencies can be injected at the application.
component level, and if not found, it will check the parent components and providers defined at the
The providedIn metadata option set to 'root' in the @Injectable() decorator ensures that the service is
module level. This allows for flexibility in managing dependencies across the application.
automatically provided at the root level.
You can also provide the service at a specific module or component level by adding it to the providers array
of the respective module or component metadata.
Example: }
import { MyService } from './my.service'; Services are commonly used for tasks such as fetching data from APIs, performing CRUD operations,
sharing data between components, implementing authentication and authorization, and more. They help in
@NgModule({ separating concerns and keeping your components lean and focused on their specific responsibilities.
providers: [MyService] Remember to provide services at the appropriate level (root, module, or component) based on your
application's needs. By utilizing services effectively, you can create more modular, reusable, and
}) maintainable Angular applications.
providers: [MyService] An Observable emits values over time, and you can subscribe to it to receive those values.
}) Example:
myObservable.subscribe(value => { To receive values emitted by an Observable, you need to subscribe to it.
console.log(value); The subscribe method takes one or more callback functions as arguments to handle the emitted values,
errors, and completion.
});
Example:
➢ Operators:
const myObservable = of('Hello', 'World');
RxJS provides a wide range of operators that allow you to transform, filter, combine, and manipulate data
streams emitted by Observables. myObservable.subscribe(
Operators like map, filter, mergeMap, tap, etc., enable you to perform various operations on emitted value => {
values.
console.log(value); // Output: Hello, World
You can chain multiple operators together to create complex data transformation pipelines.
},
Example:
error => {
import { of } from 'rxjs';
console.error(error);
import { map, filter } from 'rxjs/operators';
},
() => {
const numbersObservable = of(1, 2, 3, 4, 5);
console.log('Observable completed');
}
numbersObservable
);
.pipe(
➢ Unsubscribing from Observables:
filter(num => num % 2 === 0),
When subscribing to an Observable, the subscription object is returned. You can use this object to
map(num => num * 2) unsubscribe and stop receiving further values.
) Unsubscribing is important to prevent memory leaks and unnecessary processing when the component or
subscription is no longer needed.
.subscribe(result => {
Example:
console.log(result); // Output: 4, 8
import { Subscription } from 'rxjs'; In the component or service where you want to perform server communication, inject the HttpClient
service by declaring it as a dependency in the constructor.
const myObservable = /* create Observable */;
The HttpClient service provides methods like get, post, put, delete, etc., for making HTTP requests.
const subscription: Subscription = myObservable.subscribe(/* handle values */);
Example:
// Unsubscribe when no longer needed
import { HttpClient } from '@angular/common/http';
subscription.unsubscribe();
constructor(private http: HttpClient) { }
RxJS Observables provide a powerful way to handle asynchronous operations, compose data
transformations, and manage data streams in Angular applications. Understanding the basics of ➢ Sending GET Requests:
Observables and operators can greatly enhance your ability to handle reactive programming scenarios in
Angular. To send a GET request, use the get method of the HttpClient service, specifying the URL you want to
request.
Server Communication using HttpClient:
The get method returns an Observable that emits the server's response.
In Angular, you can communicate with a server using the built-in HttpClient module, which provides
Example:
methods to send HTTP requests and handle the server's responses. Here's an overview of how to perform
server communication using HttpClient in Angular:
this.http.get('/api/data').subscribe(response => {
➢ Import the HttpClient Module:
console.log(response);
To use HttpClient, you need to import the HttpClientModule in your Angular module.
});
Example:
➢ Sending POST Requests:
import { HttpClientModule } from '@angular/common/http';
To send a POST request, use the post method of the HttpClient service, specifying the URL and the data you
want to send.
@NgModule({
The post method also returns an Observable that emits the server's response.
imports: [
Example:
HttpClientModule
const data = { name: 'John', age: 30 };
]
this.http.post('/api/data', data).subscribe(response => {
})
console.log(response);
export class AppModule { }
});
➢ Inject and Use HttpClient:
➢ Handling Responses:
The responses from the server are typically in JSON format, and HttpClient automatically parses them into Communicating with different backend services using Angular HttpClient:
JavaScript objects by default.
In Angular, you can use the HttpClient module to communicate with different backend services, such as
You can also specify the response type explicitly using generics (<T>) when calling the HTTP methods to RESTful APIs, GraphQL APIs, WebSocket servers, and more. The HttpClient provides methods for making
receive a typed response. HTTP requests to various endpoints and handling the server's responses. Here's an overview of how to
communicate with different backend services using HttpClient in Angular:
Example:
➢ RESTful APIs:
this.http.get<User>('/api/users/1').subscribe(user => {
For communicating with RESTful APIs, you can use the HttpClient methods like get, post, put, delete, etc.
console.log(user.name);
Make sure to provide the appropriate URL and data as needed by the API.
});
Example:
➢ Error Handling:
import { HttpClient } from '@angular/common/http';
You can handle errors in the subscribe method by providing an error callback.
constructor(private http: HttpClient) { }
The error callback will be triggered if there is an error in the HTTP request or if the server responds with an
error status code. // GET request to retrieve data
this.http.get('/api/data').subscribe( console.log(response);
console.error(error); console.log(response);
} });
); ➢ GraphQL APIs:
By using HttpClient in Angular, you can easily perform HTTP requests and handle server responses in a To communicate with GraphQL APIs, you can use the HttpClient to send POST requests with the GraphQL
concise and efficient manner. The HttpClient module also provides additional features like request headers, query or mutation.
request options, interceptors, and more, allowing you to customize and enhance your server
communication logic. Make sure to provide the appropriate GraphQL endpoint URL and the GraphQL request body containing
the query/mutation.
Example: },
const query = ` },
query { () => {
name }
email );
} Depending on the backend service you want to communicate with, you might need to use specific
protocols or libraries.
`;
For example, if you are working with a server-sent events (SSE) server, you can use the EventSource API
this.http.post('/graphql', { query }).subscribe(response => { provided by the browser.
console.log(response); If you are working with a socket.io server, you can utilize the ngx-socket-io library, which provides Angular-
friendly wrappers for socket.io functionality.
});
Always refer to the documentation or specifications of the specific backend service you are using to
WebSocket Servers: determine the appropriate approach for communication.
To communicate with WebSocket servers, the HttpClient module does not provide direct support. Instead, By leveraging the HttpClient module in Angular, you can easily communicate with different backend
you can use the WebSocket object from the browser's standard API or utilize third-party WebSocket services by making appropriate HTTP requests and handling the responses. Adjust your code according to
libraries like rxjs/webSocket. the specific requirements and protocols of the backend service you are working with.
import { NgModule } from '@angular/core'; In your application's main template file (usually app.component.html), add the <router-outlet></router-
outlet> tag.
import { RouterModule, Routes } from '@angular/router';
The <router-outlet> tag acts as a placeholder where the routed components will be rendered.
const routes: Routes = [
Example:
// Define your routes here
<router-outlet></router-outlet>
];
Navigation:
@NgModule({
To navigate to a specific route or URL, you can use the Router service and its navigate method.
imports: [RouterModule.forRoot(routes)],
Provide the target route path as a parameter to the navigate method.
exports: [RouterModule]
Example:
})
import { Router } from '@angular/router';
export class AppRoutingModule { }
constructor(private router: Router) { }
➢ Define Routes:
// Navigating programmatically
In the routes array, you define your application's routes using the path and component properties.
this.router.navigate(['/about']);
The path property represents the URL path, and the component property specifies the component to
render for that URL. // Navigating with parameters
{ path: '', component: HomeComponent }, You can define route parameters in the route path by prefixing a segment with a colon (:).
{ path: 'about', component: AboutComponent }, To access the route parameters in a component, inject the ActivatedRoute service and access the params
Observable.
{ path: 'products', component: ProductsComponent },
Example:
{ path: 'products/:id', component: ProductDetailComponent },
import { ActivatedRoute } from '@angular/router';
{ path: '**', component: NotFoundComponent } // Wildcard route for handling unknown URLs
constructor(private route: ActivatedRoute) { }
];
// Accessing route parameters
this.route.params.subscribe(params => { return true;
}); Routing in Angular enables you to navigate between different components based on URL paths. By defining
routes, using the <router-outlet> tag, and leveraging the Router service, you can implement navigation
➢ Route Guards: within your Angular application. Additionally, route parameters and route guards provide additional
flexibility and control over your application's routing behavior.
Angular provides route guards that allow you to control access to routes based on certain conditions.
Router Links:
Route guards include CanActivate, CanActivateChild, CanDeactivate, Resolve, etc.
In Angular, router links are used to navigate between different routes within your application. They provide
You can implement custom route guards by creating a class that implements the corresponding guard
a declarative way to create links that trigger route navigation. Here's an overview of how to use router links
interface.
in Angular:
Example:
➢ Import the Router Module:
import { Injectable } from '@angular/core';
To use router links, you need to import the RouterModule module from @angular/router in your Angular
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from '@angular/router'; module.
}) @NgModule({
canActivate( RouterModule.forRoot([...])
next: ActivatedRouteSnapshot, ]
Example: You can add query parameters to a router link using the queryParams binding.
<!-- Router link for a route with a static path --> The queryParams property accepts an object that represents the query parameters.
<!-- Router link for a route with a dynamic parameter --> <a [routerLink]="['/products']" [queryParams]="{ category: 'electronics' }">Electronics</a>
<a [routerLink]="['/products', productId]">Product Details</a> By using router links in Angular, you can create navigation elements that automatically handle route
navigation when clicked. Router links provide a convenient and declarative way to create navigation within
<!-- Router link with additional options --> your Angular application. You can navigate to static routes, pass dynamic parameters, add query
parameters, and even style the active router links.
<a [routerLink]="['/products']" [queryParams]="{ category: 'electronics' }">Electronics</a>
Route Guards:
➢ Active Router Links:
Route guards in Angular are used to control access to routes based on certain conditions. They
To style router links based on the currently active route, you can use the routerLinkActive directive.
allow you to implement logic that determines whether a user is allowed to navigate to a particular route or
The routerLinkActive directive adds a CSS class to the element when its associated route is active. not. Angular provides several types of route guards that you can use to secure your application's routes.
Here's an overview of the different types of route guards in Angular:
You can specify the CSS class using the routerLinkActive directive's active property.
➢ CanActivate:
Example:
The CanActivate route guard determines whether a user can activate a route and navigate to it.
<a routerLink="/about" routerLinkActive="active">About</a>
It is used to protect routes based on certain conditions, such as user authentication or
<a routerLink="/products" routerLinkActive="active">Products</a> authorization.
➢ Router Link Parameters: Implement the CanActivate interface and its canActivate method, which returns a boolean or an
observable/promise that resolves to a boolean.
You can pass parameters to the router link by binding an array to the routerLink directive.
Example:
The array contains the route path segments and any route parameters.
import { Injectable } from '@angular/core';
Example:
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from
<!-- Router link with a dynamic parameter --> '@angular/router';
// Implement your logic here ): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
// Return true to allow access, or navigate to another route using UrlTree // Implement your logic here
// Return false to deny access // Return true to allow access, or navigate to another route using UrlTree
} return true;
} }
CanActivateChild: }
The CanActivateChild route guard is similar to CanActivate but specifically used for child routes. CanDeactivate:
It allows you to protect child routes of a route, ensuring that the user meets certain criteria before The CanDeactivate route guard is used to determine whether a user can deactivate a route and leave it.
accessing the child routes.
It is commonly used to show confirmation prompts or save form data before leaving a route.
Implement the CanActivateChild interface and its canActivateChild method, which returns a boolean or an
observable/promise that resolves to a boolean. Implement the CanDeactivate interface and its canDeactivate method, which returns a boolean or an
observable/promise that resolves to a boolean.
Example:
Example:
import { Injectable } from '@angular/core';
import { Injectable } from '@angular/core';
import { CanActivateChild, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from
'@angular/router'; import { CanDeactivate } from '@angular/router';
} resolve(
export class ConfirmDeactivateGuard implements CanDeactivate<CanComponentDeactivate> { // Implement your data fetching logic here
// other routes Angular allows you to implement a custom preloading strategy to control how lazy-loaded modules are
preloaded.
];
Create a custom preloading strategy by implementing the PreloadingStrategy interface.
➢ Preloading Lazy-Loaded Modules:
Implement the preload method, which takes a route and a preload function and returns an observable.
By default, lazy-loaded modules are loaded on-demand when the associated route is accessed.
Example:
However, you can also preload the lazy-loaded modules to improve the user experience.
import { Injectable } from '@angular/core';
Use the PreloadAllModules strategy from @angular/router in the AppRoutingModule to preload all lazy-
loaded modules. import { PreloadingStrategy, Route } from '@angular/router';
RouterModule.forRoot(routes, { }
}) }
], }
}) You can configure individual routes to be preloaded using the data property in the route configuration.
export class AppRoutingModule { } Set the preload key to true for the routes you want to preload.
Example: In the parent component's template where you want to render the child routes, add the <router-outlet>
tag.
const routes: Routes = [
The <router-outlet> tag acts as a placeholder for rendering the child routes.
{ path: 'admin', loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule), data:
{ preload: true } }, Example:
]; <router-outlet></router-outlet>
By lazy loading modules and preloading them, you can optimize the initial load time of your Angular ➢ Navigate to Child Routes:
application. Lazy loading and preloading ensure that only the necessary modules are loaded when required,
reducing the initial bundle size and improving the overall performance. To navigate to the child routes, you can use the routerLink directive on an anchor or button element.
Nested Routes: Specify the path to the child route relative to the parent route.
Example:
Nested routes in Angular allow you to define a hierarchical structure for your application's routes. This
enables you to have child routes within a parent route, creating a nested navigation structure. Here's how
<!-- Navigate to product details -->
you can implement nested routes in Angular:
<a routerLink="details/1">View Details</a>
➢ Configure Parent Route:
<!-- Navigate to product edit -->
Define a parent route in your route configuration using the children property.
<a routerLink="edit/1">Edit Product</a>
The children property should be an array of child route configurations.
➢ Accessing Route Parameters:
Example:
If a child route has route parameters, you can access them using the ActivatedRoute service in the child
const routes: Routes = [
component.
{ path: 'products', component: ProductsComponent, children: [
Import the ActivatedRoute service and inject it into the child component's constructor.
{ path: 'details/:id', component: ProductDetailsComponent },
Use the params observable from the ActivatedRoute to subscribe to route parameter changes.
{ path: 'edit/:id', component: EditProductComponent }
Example:
]},
import { Component, OnInit } from '@angular/core';
// other routes
import { ActivatedRoute } from '@angular/router';
];
@Component({
➢ Add <router-outlet>:
selector: 'app-product-details',
templateUrl: './product-details.component.html',
styleUrls: ['./product-details.component.css']
})
productId: string;
ngOnInit() {
this.route.params.subscribe(params => {
this.productId = params['id'];
});
By using nested routes in Angular, you can organize your application's routes in a hierarchical manner,
making the navigation structure more intuitive and manageable. Child routes can have their own
components and route parameters, allowing you to create more complex and interactive applications.
THANK YOU
HAPPY LEARNING