Showing posts with label Angular. Show all posts
Showing posts with label Angular. Show all posts

Monday, September 30, 2024

Angular Access Control CanActivate Route Guard Example

In your Angular application you may need to control access to different parts of your app. To control that kind of authorization and authentication you can use route guards in Angular.

Using route guards, you can perform some action before navigating to another route and you can restrict access to routes based on the outcome of that action. In this post we’ll see example of using CanActivate route guard to restrict access to route based on whether user is authenticated or not.


Why route guards in Angular

Use of route guards to control access in your Angular app may be considered for following scenarios-

  • User is not authorized to navigate to the component rendered by the route user want to navigate to.
  • User is not authenticated (not logged in).
  • You need to fetch some data before you display the target component.
  • You want to save pending changes before leaving a component.
  • You want to ask the user if it's OK to discard pending changes rather than save them.

Wednesday, May 29, 2024

Forms in Angular

Using forms for user input is the mainstay of any frontend application. Angular framework provides a very robust API for handling forms. In Angular there are two different approaches to handling user input through forms-

  • Template-driven forms
  • Reactive forms

Both of these approaches for handling forms in Angular provides the functionality to-

  1. Capture user inputs from the UI (View)
  2. Validating user input
  3. Creating a form model and data model
  4. Provide a way to track changes in the form and update model accordingly.

Tuesday, May 28, 2024

Angular Cross Component Communication Using Subject Observable

In this post we’ll see how to use Subject observable for cross component communication in Angular.


Subject in RxJS Library

Subject is a type of Observable using which you can multicast values to many Observers, which makes it different from a plain Observables which are unicast (each subscribed Observer owns an independent execution of the Observable).

Thursday, May 23, 2024

How to Install Node.js and NPM in Windows

This article shows how you can download and install Node.js so that you can build network applications. Installation of Node.js is also a prerequisite for developing Angular applications.

We’ll also build a simple Node.js hello world application to verify the Node.js installation.


Downloading Node.js

You can download latest Node.js version from this location- https://nodejs.org/en/download/

Node.js download

Installing Node.js

Double click on the downloaded Windows Installer (.msi) file to start the installation.

Nodejs installation

Double click on the downloaded Windows Installer (.msi) file to start the installation. Follow the instructions which includes-

  1. Accepting the license term
  2. Select the location where you want to install nodejs.
  3. Select the components to be installed.
  4. Check the box to automatically install tools for native modules.
  5. Click install button to start installation.

Checking for NPM

The Node Pack Manager (NPM) should also get installed as part of Node.js installation. To check if it is successfully installed, run the following command from command prompt.

npm -v

It should display version number for the NPM installation.

Checking Node.js installation

To verify Node.js installation you can run a simple Node.js HelloWorld application. Save the following code as helloworld.js.

const http = require('http');

const hostname = '127.0.0.1';
const port = 9000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

Here http functionality is required so first thing is to specify it using require() function.

In the script http server is created which listens on port 9000. For any request received it sends ‘Hello World’ as response.

Navigate to the directory where helloworld.js is saved and run the following command.

F:\NETJS>Node helloworld.js

That starts the server which starts listening on port 9000. You can start a browser and type the following URL.

http://localhost:9000/

nodejs hello world

That's all for this topic How to Install Node.js and NPM in Windows. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Angular Tutorial Page


Related Topics

  1. Introduction to Node.js
  2. Node.js REPL
  3. Angular Project Structure With File Description
  4. How to Setup Angular
  5. Angular First App - Hello world Example

You may also like-

  1. Angular Example to Render Multiple Rows
  2. How to Add Bootstrap to Angular Application
  3. Creating New Component in Angular
  4. Serialization in Java
  5. Object Cloning in Java
  6. Garbage Collection in Java
  7. Spring Web MVC Example With Annotations And XML Configuration
  8. Introduction to Hadoop Framework

Monday, April 29, 2024

Checkbox in Angular Form Example

In this post we’ll see how to use check boxes in Angular form. We’ll see examples of adding check boxes to both template-driven and reactive form in Angular.

Checkbox in Reactive form Angular example

In this Angular Reactive form example we’ll have a form with two input fields for name and date (with a date picker for picking date) and a group of check boxes to select favorite exercises.

Thursday, April 25, 2024

FormGroup in Angular With Examples

Using FormGroup in Angular forms you can group FormControl instances and track the value and validity state of those instances as a group rather than for each individual FormControl instance. In this post we'll see example of using FormGroup with Angular template-driven form as well as with Reactive form.


Friday, April 19, 2024

Radio Button in Angular Form Example

In this post we’ll see how to use radio buttons in Angular form. We’ll see examples of adding radio button to both template-driven and reactive form in Angular.


Radio button in template driven form example

In this Angular template driven form example we’ll have a form with two input fields for name and email, a date picker for picking date and a group of radio buttons to select membership type.

Wednesday, April 17, 2024

FormBuilder in Angular Example

In this tutorial we’ll see how to use FormBuilder in Angular to create a form. FormBuilder is a helper class that reduces the boilerplate code while building a form. It shortens the code to create instances of a FormControl, FormGroup, or FormArray.

Steps needed to use FormBuilder

  1. Import the FormBuilder class.
    import { FormBuilder } from '@angular/forms';
    
  2. Inject the FormBuilder service.
    constructor(private fb: FormBuilder) { }
    
  3. Generate the form contents. The FormBuilder has three factory methods: control(), group(), and array() used to generate instances of FormControl, FormGroup, and FormArray in your component classes.

Wednesday, April 10, 2024

Angular Custom Property Binding Using @Input Decorator

In the post Angular Property Data Binding we saw how to bind data to a property of an element. We can also bind a custom property of an Angular component that’s what we’ll see in this post how to bind custom property in Angular using @Input decorator.


Angular custom property binding

Using custom property binding to set the model property of a custom component is a great way for parent and child components to communicate. For example following statement in the parent template shows the binding for the property "childItem" in the child component.

<app-child [childItem]=“parentItem”></app-child> 
  • Here <app-child> is the selector defined in the child component.
  • childItem is a field in the child component.
  • parentItem is a field in parent component.

By using custom property binding here, childItem is bound to the value of the parentItem. But that needs one more thing to work properly, using @Input decorator.

Using @Input decorator in custom property binding

By default any property in a component is accessible with in the component where it is defined. If you want to expose any property outside of the component then that property has to be decorated with @Input decorator.

export class UserComponent {
  @Input() usr: User;
  ...
  ...
}

With usr property decorated with @Input decorator, parent component can bind to this property of the child component.

@Input decorator marks a class field as an input property. The input property is bound to a DOM property in the template. During change detection, Angular automatically updates the data property with the DOM property's value.

Angular custom property binding example

The requirement is to show user details in a child component where each user instance is passed from the parent component. Thing to notice here is that use of @Input decorator gives you a chance to break your code into separate components which promotes reusing of components. Here child component can be termed as a presentational component.

Creating a User class

Create a Type script class user.model.ts to define a User class. If you are aware of MVC (Model View Controller) pattern then this class is the Model. There are 3 fields name, age and joinDate in the User class.

user.model.ts

export class User {
  name : string;
  age : number;
  joinDate : Date;
  constructor(name: string, age : number, joinDate : Date) {
    this.name = name;
    this.age = age;
    this.joinDate  = joinDate;
  }
}

app.component.ts (Parent component)

import {Component} from '@angular/core';
import { User } from './user/user.model';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  users: User[];
  constructor(){
    //Adding User instances to users array
    this.users = [new User('Jack', 56, new Date('2005-03-25')),
    new User('Lisa', 32, new Date('2012-05-09')),
    new User('Jayesh', 28, new Date('2014-10-21'))] ;
  }
}

AppComponent uses User model so that is imported. An array of type User is defined and user instances are added to that array in the Constructor.

app.component.html

<div class="container">
  <h3>User Details</h3>
  <app-user *ngFor="let user of users" 
               [usr]="user">
  </app-user>
</div>

In the template with in the <app-user> selector users array is iterated using ngFor directive and each user instance is bound to the usr property of the child component.

user.component.ts (Child component)

import { 
    Component, Input
 } from '@angular/core';
import { User } from './user.model';
@Component({
  selector: 'app-user',
  templateUrl: './user.component.html'
})
export class UserComponent {
  @Input() usr!: User;
}

In the child component usr variable is decorated with @Input decorator indicating that parent component can bind to this property. Note that non-null assertion operator (!) is used here to suspend strict null and undefined checks for the usr property.

User.component.html

In the template user data is displayed using string interpolation.

<div class="row">
  <div class="col-xs-6">
    <label>Name: </label> {{ usr.name }}
    <label>Age: </label> {{ usr.age }}
    <label>Join Date: </label> {{ usr.joinDate | date:'dd/MM/yyyy' }}
  </div>
</div>
Angular Custom Property Binding

That's all for this topic Angular Custom Property Binding Using @Input Decorator. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Angular Tutorial Page


Related Topics

  1. Angular Style Binding With Examples
  2. Angular Two-Way Data Binding With Examples
  3. Angular Custom Event Binding Using @Output Decorator
  4. Angular Custom Two-Way Data Binding
  5. How to Install Node.js and NPM in Windows

You may also like-

  1. Angular ngClass Directive With Examples
  2. Angular Cross Component Communication Using Subject Observable
  3. Setting Wild Card Route in Angular
  4. FormArray in Angular With Example
  5. Java Multithreading Interview Questions And Answers
  6. How to Sort HashSet in Java
  7. How to Convert Date And Time Between Different Time-Zones in Java
  8. Convert String to int in Python

Tuesday, April 9, 2024

Angular Custom Event Binding Using @Output Decorator

In the post Angular event binding we saw how event binding allows you to listen and respond to the events sent by the host elements. We can also bind a custom event of an Angular component that’s what we’ll see in this post how to bind custom event in Angular using @Output decorator.


Angular custom event binding

Using custom event binding is a great way for parent and child components to communicate where parent component is informed of any change in the child component. For example following statement in the parent template shows the event binding for the property "onUserSelected" in the child component.

Statement in parent component-

<app-user *ngFor="let user of users" 
            [usr]="user" (onUserSelected)="showUser($event)">

Property in child component-

@Output() onUserSelected: EventEmitter<User>;

@Output decorator, $event and EventEmitter

While doing a custom event binding in Angular three things you will come across are-

  1. @Output decorator
  2. EventEmitter class
  3. $event object

1. @Output decorator

A property in a Component that emits a custom event is decorated with @Output decorator. For example in the statement

@Output() onUserSelected: EventEmitter<User>;

onUserSelected is decorated with @Output() which means this property is going to emit a custom event. That is why this property is of type EventEmitter.

2. EventEmitter class

EventEmitter class is used in components with the @Output to emit custom events synchronously or asynchronously. EventEmitter maintains a list of subscribing instances and register handlers for the event.

EventEmitter class has two methods-

  • emit(value?: T)- Emits an event containing a given value, T signifies the value to emit.
  • subscribe()- Registers handlers for events emitted by this instance.

When we assign an EventEmitter to an output, subscription of instances is automatically done by Angular so you don't need to use this method explicitly in most of the scenarios.

3. $event object

In an event binding, Angular sets up an event handler for the target event. The binding conveys information about the event. This information is encapsulated in $event and may include data values such as an event object, string, or number.

When the event is raised, the handler executes the template statement. For example in the following statement

(onUserSelected)="showUser($event)"

(onUserSelected) is the target event

showUser($event) is the template statement.

When the event onUserSelected is raised, template statement, which in our example is showUser($event) method, is executed. Argument of the showUser() method is $event which encapsulates the value passed as method parameter.

Angular custom event binding example

We have got enough information about the event binding and the parts that form the custom event binding. Let’s create an example using that knowledge now. Note than example is created using Angular 17 and Bootstrap 5.

In the example there are two child components UserComponent and UserDataComponent and AppComponent is the parent component.

Initially list of user names is displayed (Done through UserComponent), on clicking any of the user User details are displayed (Done through UserDataComponent).

user.model.ts

In the Model class there are 3 fields name, age and joinDate.

export class User {
  name : string;
  age : number;
  joinDate : Date;
  constructor(name: string, age : number, joinDate : Date) {
    this.name = name;
    this.age = age;
    this.joinDate  = joinDate;
  }
}

app.component.ts (Parent component)

AppComponent uses User model so that is imported. An array of type User is defined and user instances are added to that array in the Constructor. Property selectedUser stores the value of the User which is selected and used to display details for the selected User. When the custom event is raised showUser() method gets called which assigns value to the selectedUser property.

import {Component} from '@angular/core';
import { User } from './user/user.model';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  users: User[];
  selectedUser!: User;
  constructor(){
    //Adding User instances to users array
    this.users = [new User('Jack', 56, new Date('2005-03-25')),
                  new User('Lisa', 32, new Date('2012-05-09')),
                  new User('Jayesh', 28, new Date('2014-10-21'))
                 ] ;
  }
  showUser(user: User) : void {
    // Setting selected user
    this.selectedUser = user;
  }
}

app.component.html

<div class="container">
  <h3>Click User to get details</h3>
  <app-user 
      *ngFor="let user of users" 
      [usr]="user" (onUserSelected)="showUser($event)">
  </app-user>

  <user-data *ngIf="selectedUser" [user]="selectedUser"></user-data>
</div>

Template has two selectors tags for the child templates. With in the <app-user> selector users array is iterated using ngFor directive and each user instance is bound to the usr property of the child component, onUserSelected is the output property (to emit event).

user.component.ts (Child component)

import { Component, Input, Output, EventEmitter } from '@angular/core';
import { User } from './user.model';
@Component({
  selector: 'app-user',
  templateUrl: './user.component.html'
})
export class UserComponent {
  @Input() usr!: User;
  @Output() onUserSelected: EventEmitter<User>;
  constructor(){
    this.onUserSelected = new EventEmitter();
  }
  userClicked() : void{
    this.onUserSelected.emit(this.usr);
  }
}

In the child component usr variable is decorated with @Input decorator indicating that parent component can bind to this property.

onUserSelected is decorated with @Output indicating that it will emit an event.

In the userClicked() method using emit method an event is emitted with current user instance as event value which will be encapsulated in $event.

User.component.html

In the template user name is displayed, there is also an even binding for click event which calls the userClicked() method. Execution of userClicked() method results in emitting the event with the user instance as value.

<div class="row">
  <div class="col-xs-6">
    <label>Name:</label><span (click)='userClicked()'> {{ usr.name }}</span>
  </div>
</div>

userdata.component.ts (Child component)

import { 
  Component, Input
 } from '@angular/core';
import { User } from './user.model';
@Component({
  selector: 'user-data',
  templateUrl: './userdata.component.html'
})
export class UserDataComponent{
  @Input() user!: User;
}

Another child component UserDataComponent has a property user which is decorated with @Input decorator indicating that parent component can bind to this property. This is property to which selected user is assigned and then used to display user details.

userdata.component.html

This template shows the user details.

<div class="mt-4 p-3 bg-light">
  <h2>User Details</h2>
  <div class="row">
    <div class="col-xs-5 px-3">
      <label>Name: </label> {{ user.name }}      
    </div>
    <div class="col-xs-4 px-3">
      <label>Age: </label> {{ user.age }}
    </div>
    <div class="col-xs-4 px-3">
      <label>Joining Date: </label> {{ user.joinDate | date:'dd/MM/yyyy'}}
    </div>
  </div>
</div>

Testing the application

Initially user names are displayed.

Angular Custom Event Binding

When user name is clicked

Custom Event Binding Example

That's all for this topic Angular Custom Event Binding Using @Output Decorator. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Angular Tutorial Page


Related Topics

  1. Angular Custom Property Binding Using @Input Decorator
  2. Angular Custom Two-Way Data Binding
  3. Angular Style Binding With Examples
  4. Angular Example to Render Multiple Rows
  5. Angular @Input and @Output Example

You may also like-

  1. Angular ngClass Directive With Examples
  2. Angular @Component Decorator
  3. Service in Angular With Examples
  4. Angular Disable Button Example
  5. Multiple Catch Blocks in Java Exception Handling
  6. intern() Method in Java String
  7. Varargs (Variable-length Arguments) in Java
  8. Spring Batch Processing With List of Objects in batchUpdate() Method

Monday, April 8, 2024

Angular Custom Two-Way Data Binding

In the post Angular Two-Way Data Binding With Examples we saw how two way binding can be done using ngModel and it is a combination of both property binding and event binding. In this post we’ll see how to do custom two way data binding in Angular.

Angular custom two way data binding

You can use a custom property for two way data binding, for example-

<app-counter [(counter)]="counterValue"></app-counter>

Here counter is a property that has two way data binding. In the component you should have a counter property that can be assigned a value and a corresponding event named counterChange. Note that this convention has to be followed, the event name has to be ‘property name + change’.

Angular custom two way data binding example

Here is a simple example of custom two way data binding. There is a child component that displays the counter value and has buttons to decrement or increment counter value.

counter.component.html

<div>
  <label>Value </label> {{counter}}
  <hr/>
  <button class="btn btn-primary me-2" (click)="dec()">-</button>
  <button class="btn btn-primary" (click)="inc()">+</button>
</div> 

counter.component.ts

import { Component, Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-counter',
  templateUrl: './counter.component.html'
})
export class CounterComponent{
  @Input() counter: number = 0;
  //event name has to be 'property name + change'
  @Output() counterChange = new EventEmitter<number>();

  dec(){
    --this.counter;
    this.counterChange.emit(this.counter);
  }
  inc(){
    ++this.counter;
    this.counterChange.emit(this.counter);
  }
}

In the component, counter property is decorated with @Input decorator which means property binding where value of counter is expected from the parent component through this binding.

There is also an event binding done using counterChange. Whenever decrement or increment button is clicked value of counter is changed and that changed value is emitted using counterChange event emitter.

app.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'], 
})
export class AppComponent{
  counterValue = 5;
}

app.component.html

<div class="container">
  <div class="row">
    <div class="col-sm-6">       
      <app-counter [(counter)]="counterValue"></app-counter>
      <label>Value of the counter is </label> {{counterValue}}
    </div>
  </div>
</div>

Here AppComponent.counterValue is two-way bound to the CounterComponent. counter property of CounterComponent gets its initial value from AppComponent.counterValue ( counterValue = 5 in AppComponent). Clicking the decrement and increment buttons updates the AppComponent.counterValue via the two-way binding.

So, there is a property binding where child property is bound to the parent property and there is also an event binding from child to parent causing the change in counter value.

Initial screen

On clicking decrement.

That's all for this topic Angular Custom Two-Way Data Binding. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Angular Tutorial Page


Related Topics

  1. Angular Custom Property Binding Using @Input Decorator
  2. Angular Custom Event Binding Using @Output Decorator
  3. Angular Style Binding With Examples
  4. Angular @Input and @Output Example
  5. Angular ngSwitch Directive With Examples

You may also like-

  1. Injector Hierarchy and Service Instances in Angular
  2. Angular - Call One Service From Another
  3. Forms in Angular
  4. Angular Project Structure With File Description
  5. Java String Interview Questions And Answers
  6. Java BlockingQueue With Examples
  7. Spring Boot spring-boot-starter-parent
  8. Apache Avro Format in Hadoop

Sunday, April 7, 2024

FormArray in Angular With Example

FormArray in Angular provides another way to group any number of controls apart from FormGroup in Angular. Difference between FormGroup and FormArray is that in FormGroup each child FormControl is added as the part of FormGroup object as a key, value pair where control name is the key. In FormArray value of each child FormControl is added into an array.

Since FormArray internally maintains an array of FormControls so it is easy to add or remove controls from it giving you capability to create a dynamic form using FormArray in Angular.

Friday, April 5, 2024

Angular Two-Way Data Binding With Examples

In this article you will learn how to do two-way data binding in Angular using ngModel directive.


What is two-way binding

Angular one way data binding provides unidirectional binding either:

From component (Type Script code) to template (HTML view) in the form of String interpolation, property binding.

OR

From template (HTML view) to component (Type Script code) in the form of event binding.

In Angular two-way binding both of these one way bindings are combined to create a two-way flow of data between a component class and its template. So, two-way binding does both of these-

  1. If a property in the component is changed that change flows to the view.
  2. Same way change in view is reflected in the bound property in the component.

You can see that the former is property binding where as the latter is event binding and the combination of both results in two-way binding in Angular.

Angular Two-Way Data Binding

Syntax of Angular two-way binding

Syntax for two-way data binding in Angular is [()]. The [()] syntax combines the brackets of property binding, [], with the parentheses of event binding, ().

This syntax for two-way binding is also known as banana in a box.

[( )] = BANANA IN A BOX

It is just a visual way to remember that the parentheses go inside the brackets.

How to use two-way binding in Angular

In Angular ngModel directive is used for two-way bindings. It simplifies creating two-way data bindings on form elements like input element.

[(ngModel)] = "[PROPERTY_IN_COMPONENT]"  

For example: <input type="text" [(ngModel)]="userName" />

If userName property in the component has an initial value that is shown as the value of the input. Also any change in the value done by the user in the view changes the bound property value in the component too.

For using the ngModel directive in a two-way data binding, you must do these two things-

  • Import the FormsModule
  • Add it to the NgModule's imports list
import { FormsModule } from '@angular/forms';
..
..
@NgModule({
  ..
  ..

  imports: [
    BrowserModule,
    FormsModule
  ],
  ..
  ..
})
export class AppModule { }

You could achieve the same result with separate bindings to the <input> element's value property and input event:

<input [value]="userName" (input)="userName=$event.target.value">

or like this-

<input [ngModel]="userName" (ngModelChange)="userName=$event">

Using [(ngModel)] simplifies the two-way data binding with a shorter syntax. Note that, this [(ngModel)] syntax can only set a data-bound property. If you need to do something more, you can write the expanded form as shown above. For example, the following changes the <input> value to uppercase:

<input [ngModel]="userName" (ngModelChange)="setUppercaseName($event)">

Angular two-way binding example

1. Here is an example with a single property userName in the component.

import { 
  Component
 } from '@angular/core';
@Component({
  selector: 'app-user',
  templateUrl: './user.component.html'
})
export class UserComponent {
  userName = "Rita";
  constructor(){}  
}

Template

<div>
  <label for="username">User Name:</label>
  <input [(ngModel)]="userName" id="username">
  <p>{{ userName }}</p>
</div>

In the template as you can see target of two-way binding is ngModel directive and the expression is the property "userName" property of the component.

On running the example you get the output as-

angular twoway data binding example

Since property “userName” has an initial value so that value is displayed in the template.

Now if you change that value in the input element, that changed value would be reflected in the component too. Using String interpolation that value is fetched from the component and shown below the input element.

2. Two-way binding with fields of a model can be done in a similar way. Let’s say there is a Model class User with 2 fields name and age.

user.model.ts

export class User {
  name: string;
  age: number;
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}

user.component.ts

In the component, instance of the Model class User is created and initialized with values.

import { Component } from '@angular/core';
import { User } from './user.model';
@Component({
  selector: 'app-user',
  templateUrl: './user.component.html'
})
export class UserComponent {
  user: User;
  constructor(){
    // Initializing User instance
    this.user = new User('Jack Ryan', 56);
  }
}

user.component.html

<div class="container">
  <div class="mb-3">
    <label for="username" class="form-label">User Name</label>
    <input class="form-control" [(ngModel)]="user.name" id="username">
    <p>{{ user.name }}</p>
  </div>
  <div class="mb-3">
    <label for="age" class="form-label">Age</label>
    <input class="form-control" id="age" [(ngModel)]="user.age">
    <p>{{ user.age }}</p>
  </div>
</div>

That's all for this topic Angular Two-Way Data Binding With Examples. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Angular Tutorial Page


Related Topics

  1. Angular Custom Two-Way Data Binding
  2. Angular Attribute Binding With Examples
  3. Angular @Input and @Output Example
  4. Angular ngIf Directive With Examples
  5. Angular ngClass Directive With Examples

You may also like-

  1. Injector Hierarchy and Service Instances in Angular
  2. What is Client Side Routing in Angular
  3. Checkbox in Angular Form Example
  4. How to Setup Angular
  5. Inter-thread Communication Using wait(), notify() And notifyAll() in Java
  6. Serialization and Deserialization in Java
  7. Reading Delimited File in Java Using Scanner
  8. Bubble Sort Program in Python

Monday, April 1, 2024

Angular Reactive Form Validation Example

In the post Angular Reactive Form Example we saw an example of creating a simple Reactive form in Angular in this post we’ll add to that example to create an Angular reactive form with validation.

Tracking control states

NgModel directive used with the form controls tracks the state of that control. Three things you'll look for while validating form fields are-

  1. Whether user touched the control or not,
  2. If the value of the form control is changed
  3. If the entered value is valid or invalid.

Saturday, March 30, 2024

Angular Class Binding With Examples

In this post we’ll discuss another one-way binding known as Angular class binding. Using class binding you can add and remove CSS classes dynamically from an element's class attribute.

Angular class binding syntax

Syntax of class binding is similar to property binding, square brackets are used for class binding too. To create a class binding, start with the prefix class followed by a dot (.) and the name of the CSS class.

[class.CSS_CLASS]="isRequired"

Here CSS class CSS_CLASS is added when the bound expression is truthy (i.e. isRequired is true), and it removes the class when the expression is falsy (i.e. isRequired is false).

Adding multiple CSS classes

Angular class binding can also be done to multiple classes by using a generic [class] binding without the dot (for example, [class]="classExpr").

The expression can be a space-delimited string of class names. For example

[class]="my-class-1 my-class-2 my-class-3"

You can format it as an object (object, Array, Map, Set, etc) with class names as the keys and truthy/falsy expressions as the values.

As key/value pair- [class]="{my-class-1: true, my-class-2: false}”

As an array - [class]=['my-class-1', 'my-class-2']

Angular class binding examples

1. In the example we display region wise sales figures and want to highlight the sales figures which are good in different color and the sales figures which are not satisfactory in different color. For that styling class binding is used with the condition on the sales figures.

region.model.ts

Model class with fields.

export class Region {
  region: string;
  regionalManager: string;
  sales: number;
  constructor(region: string, regionalManager: string, sales: number) {
    this.region = region;
    this.regionalManager = regionalManager;
    this.sales  = sales;
  }
}

Component class

Component used Region model so that class is imported. There is an array of type Region in which instances of Region are stored.

import { 
    Component
 } from '@angular/core';
import { Region } from './region.model';
@Component({
  selector: 'app-region',
  templateUrl: './region.component.html',
  styleUrls: ['./region.component.css']
})
export class RegionComponent{
  regions: Region[];
  constructor(){
    //Adding Region instances to regions array
    this.regions = [new Region('East', 'Jack', 145),
                   new Region('West', 'Jerry', 225),
                   new Region('North', 'Lisa', 300),
                   new Region('South', 'Randy', 175)] ;
  }
}

CSS Class

.domore {
  background-color: #d41e2e;
  color: #ffffff;
}
.satisfactory {
  background-color:green;
  color: #ffffff;
}

Template

<div class="container">
  <table class="table table-sm table-bordered mt-4">
    <tr>
      <th>Region</th>
      <th>Manager</th>
      <th>Sales (in millions)</th>
    </tr>
    <tr *ngFor="let region of regions" [class.domore] = "region.sales < 150"
      [class.satisfactory] = "region.sales > 250">
      <td>{{region.region}}</td>
      <td>{{region.regionalManager}}</td>
      <td>{{region.sales}}</td>
    </tr>
  </table>
</div>

With the <tr> element there are two class bindings

 [class.domore] = "region.sales < 150"
 [class.satisfactory] = "region.sales > 250"

When sales is less than 150 domore CSS class is added, when sales is greater than 250 then satisfactory CSS class is added.

class binding example

2. In this example we’ll see how to do class binding for multiple CSS classes. To demonstrate that one more CSS class is added.

CSS

.domore {
  background-color: #d41e2e;
  color: #ffffff;
}
.satisfactory {
  background-color:green;
  color: #ffffff;
}
.brd {
  border: 2px solid black;
}

Component

import { 
  Component
} from '@angular/core';
import { Region } from './region.model';
@Component({
  selector: 'app-region',
  templateUrl: './region.component.html',
  styleUrls: ['./region.component.css']
})
export class RegionComponent{
  regions: Region[];
  constructor(){
  //Adding Region instances to regions array
  this.regions = [new Region('East', 'Jack', 145),
                  new Region('West', 'Jerry', 225),
                  new Region('North', 'Lisa', 300),
                  new Region('South', 'Randy', 175)];
  }

  getCssClasses(sales : Number){
    if(sales < 150){
      return "domore brd";
    }else if(sales > 250){
      return "satisfactory brd";
    }
  }
}

In the component a method getCssClasses() is added in which sales figures are passed as argument. Based on the condition two CSS classes are passed.

Template

<div class="container">
  <table class="table table-sm table-bordered mt-4">
    <tr>
      <th>Region</th>
      <th>Manager</th>
      <th>Sales (in millions)</th>
    </tr>
    <tr *ngFor="let region of regions" [class] = "getCssClasses(region.sales)">
      <td>{{region.region}}</td>
      <td>{{region.regionalManager}}</td>
      <td>{{region.sales}}</td>
    </tr>
  </table>
</div>

In the <tr> element generic class binding is used with a bound method. From the method, space delimited string of CSS class names is returned.

Angular Class Binding

That's all for this topic Angular Class Binding With Examples. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Angular Tutorial Page


Related Topics

  1. Angular Style Binding With Examples
  2. Angular Attribute Binding With Examples
  3. Angular Custom Event Binding Using @Output Decorator
  4. Angular Custom Two-Way Data Binding
  5. Angular ngClass Directive With Examples

You may also like-

  1. Angular Disable Button Example
  2. Angular @Component Decorator
  3. Angular - Call One Service From Another
  4. How to Add Bootstrap to Angular Application
  5. JVM Run-Time Data Areas - Java Memory Allocation
  6. Adding Tomcat Server to Eclipse
  7. Java Reflection API Tutorial
  8. static Reference to The Non-static Method or Field Error

Tuesday, March 26, 2024

Angular Form setValue() and patchValue()

In this tutorial we’ll see how to set values for the form controls using setValue and patchValue in Angular forms. We’ll also see the difference between setValue and patchValue methods.


setValue in Angular

setValue as the name suggests is a method used to set values. You can use it to set value of a single form control instance, form group or form array.

Monday, March 18, 2024

Injector Hierarchy and Service Instances in Angular

In the Service in Angular With Examples post we saw an example of creating service where provider metadata was provided with in the @Injectable() decorator.

@Injectable({
 providedIn: 'root',
})

But that is not the only way to register a provider in Angular, there is a complete injector hierarchy and the number of service instances created depends on how you register the provider.


Providing services at different levels

For any service you are going to use in your Angular app you must register at least one provider. The provider can be part of the service's own metadata, making that service available everywhere, or you can register providers with specific modules or components. There are the following three ways for registering a provider for the service.

1. In the @Injectable() decorator for the service itself. By default, the Angular CLI command ng generate service registers a provider with the root injector for your service by including provider metadata in the @Injectable() decorator.

@Injectable({
 providedIn: 'root',
})

When you provide the service at the root level, Angular creates a single, shared instance of the Service and injects it into any class that asks for it. As per Angular docs Using the @Injectable() providedIn property is preferable to the @NgModule() providers array because that allows Angular to optimize an app by removing the service from the compiled app if it isn't used, this process of optimization is knows as tree-shaking.

2. You can also register a provider with a specific NgModule. In that case same servcie instance is available to all components in that NgModule.

For example configuring an app-wide provider in the @NgModule() of AppModule. You will have to use the providers property of the @NgModule() decorator.

@NgModule({
  providers: [LoggerService],
  bootstrap: [AppComponent]
})
export class AppModule { }

3. You can also register a provider at the component level, in that case you get a new instance of the service with each new instance of that component.

To register a service provider at the component level you can use the providers property of the @Component() decorator.

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

Injector hierarchies in Angular

Based on these types of service providers there are two injector hierarchies in Angular.

  • ModuleInjector hierarchy— Configure a ModuleInjector in this hierarchy using an @NgModule() or @Injectable() annotation. A single service instance will be used at the root level or modulr level based upon the configuration used.
  • ElementInjector hierarchy— Angular creates ElementInjectors implicitly for each DOM element. When you provide services in a component, that service is available via the ElementInjector at that component instance. It will also be available at child components if you are not providing it again in the child component using the providers property.

Service provider example using @Injectable() decorator

In the post Service in Angular With Examples there is an example of creating a LoggerService which is decorated with @Injectable() decorator to provide the metadata that allows Angular to inject it into a component as a dependency.

Service provider example using @NgModule

Let’s see the same example by registering service in providers array of @NgModule.

LoggerService class

Now @Injectable decorator is not used in LoggerService class.

export class LoggerService {
  constructor() { }
  log(msg: string) { 
    console.log(msg); 
  }
  error(msg: string) { 
    console.error(msg); 
  }
}

Service is registered in the AppModule class now, refer the providers properties of @NgModule decorator.


import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { UserComponent } from './user/user.component';
import { LoggerService } from './services/logger.service';

@NgModule({
  declarations: [
    AppComponent,
    UserComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule
  ],
  providers: [LoggerService],
  bootstrap: [AppComponent]
})
export class AppModule { }

Service provider example at component level

In an example for registering provider at component level we’ll create an Angular application that shows the existing user and has a UI to add a new User.

Angular injector hierarchy

When a new user is added and submit button is clicked that user details should be added to the list of existing users.

Angular injector and service instance

After submit button is clicked.

In the example there is a UserService class that has an array of users and a function to add new user.

import { User } from '../user/user.model';

export class UserService {
  users = [new User('Jack', 62, new Date('2005-03-25')),
  new User('Olivia', 26, new Date('2014-05-09')),
  new User('Manish', 34, new Date('2010-10-21'))] ;

  addUser(user: User){
    this.users.push(user);
  }
}

For User objects a User model class is used.

export class User {
  name : string;
  age : number;
  joinDate : Date;
  constructor(name: string, age : number, joinDate : Date) {
    this.name = name;
    this.age = age;
    this.joinDate  = joinDate;
  }
}

AppComponent class

This is the component class where UserService is configured with in the providers array. In the ngOnInit() method all the existing users are assigned to the users variable, which is an array of type User, by calling the UserService.

import { Component, OnInit } from '@angular/core';
import { User } from './user/user.model';
import { UserService } from './services/user.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'], 
  providers: [UserService]
})
export class AppComponent implements OnInit{
  users: User[] = [];
  constructor(private userService: UserService){}
  ngOnInit(){
    this.users = this.userService.users;
  }
}

app.component.html

Template has selector tags for the child components.

<div class="container">
  <div class="row">
    <div class="col-xs-12 col-md-8">
      <app-adduser></app-adduser>
      <h3>User Details</h3>
      <app-user *ngFor="let u of users" [user]="u"></app-user>
    </div>
  </div>
</div>

AddUserComponent

In the AddUserComponent which is the child component of the AppComponent, UserService is provided again. There is also a method addUser() that gets the entered value for the new User, create a User object and call the addUser() method of the userService to add the entered user to the array of existing users.

import { User } from './user.model';

@Component({
  selector: 'app-adduser',
  templateUrl: './adduser.component.html',
  styleUrls: ['./adduser.component.css'],
  providers: [UserService]
})
export class AddUserComponent {
 
  constructor(private userService: UserService){}

  addUser(name: HTMLInputElement, age: HTMLInputElement, date: HTMLInputElement){
    this.userService.addUser(new User(name.value, Number(age.value), new Date(date.value)));
    // resetting input elements
    name.value = '';
    age.value = '';
    date.value = '';
  }
}
adduser.component.html

HTML template for providing a UI to add new user. It has three fields for name, age and joining date and a submit button. There is also click event binding calling the addUser() method.

<div class="row">
  <div class="col-xs-12 col-md-8">
    <div class="form-group">
      <label for="name">Name:</label>
      <input class="form-control" placeholder="Enter name" id="name" #enteredname>
    </div>
    <div class="form-group">
      <label for="age">Age:</label>            
      <input class="form-control" placeholder="Enter age" id="age" #enteredage>
    </div>      
    <div class="form-group">
      <label for="joindate">Joining Date:</label>    
      <input class="form-control" placeholder="Enter joining date" id="joindate" #entereddate>
    </div>
    <button (click)="addUser(enteredname, enteredage, entereddate)" class="btn btn-primary">Submit</button>
  </div>
</div>
UserComponent

In the component class there is a property binding using @Input decorator. In the AppComponent template there is a for loop that binds user to this property in each iteration, that’s how user details are displayed.

import { Component, OnInit, Input } from '@angular/core';
import { User } from './user.model';

@Component({
  selector: 'app-user',
  templateUrl: './user.component.html',
  styleUrls: ['./user.component.css']
})
export class UserComponent implements OnInit {
  @Input() user: User;
  
  ngOnInit(): void {
  }
}

user.component.html

<div class="container">
  <div class="row">
    <div class="col-xs-12 col-md-8 px-3">
      <p>{{user.name}} {{user.age}} {{user.joinDate | date:'dd/MM/yyyy'}}</p>
    </div>
  </div>
</div>

So these are all the classes and if you have got everything right then you can try to add new user. It won’t add it to the users array and you won’t see any new User details. That will happen because of the provider at the child component too. In the AddUserComponent too a provider is registered, that results in the creation of new UserService instance overriding the instance created by the provider at the AppComponent level.

If you have registered a service provider at parent component level, the created service instance is used by the child components too if they don't register their own provider. In this example since child component registers its own provider so a new service instance is created for the child component.

When you add a new user from AddUserComponent it is added to the array attached to the UserService instance of AddUserComponent. The details which are showed using the user property of UserComponent gets user from the array which is attached to the UserService instance of AppComponent. That is why new user details are not added.

You can comment the providers property in the @Component decorator of the AddUserComponent. Now only Single instance of UserService is created at the AppComponent level (Parent component), child component AddUserComponent shares the same instance.

@Component({
    selector: 'app-adduser',
    templateUrl: './adduser.component.html',
    styleUrls: ['./adduser.component.css'],
    //providers: [UserService]
  })
  export class AddUserComponent {
 ..
 ..
 }

That's all for this topic Injector Hierarchy and Service Instances in Angular. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Angular Tutorial Page


Related Topics

  1. Angular - Call One Service From Another
  2. Creating New Component in Angular
  3. Angular ngFor Directive With Examples
  4. Angular @Input and @Output Example
  5. Angular Disable Button Example

You may also like-

  1. Angular Two-Way Data Binding With Examples
  2. Angular One-Way Data Binding Using String Interpolation
  3. Angular Routing Concepts With Example
  4. Angular Access Control CanActivate Route Guard Example
  5. ConcurrentHashMap in Java
  6. BigDecimal in Java
  7. Spring MVC - Binding List of Objects Example
  8. Bubble Sort Program in Python

Sunday, March 17, 2024

Angular - Call One Service From Another

In the Service in Angular With Examples post we saw how Components in Angular should only concentrate on view-related functionality. Any application logic like fetching data through server calls, user input validation, logging to console should be delegated to a service in Angular. It doesn’t mean that all the application logic for a component has to go in a single service, you can create separate services for different functionalities and then call one service from another in Angular application. In this post we’ll see how to call one service from another in Angular.

Angular Service that needs another service

A service in Angular may have a dependency on another service, for example you may have a DataService to get data from backend, SecurityService to secure your app, LoggerService to log to log file and these classes may have interdependency.

You don’t have to do much to configure dependency between services. A service that needs another service should have a @Injectable decorator and then you can apply the same constructor injection pattern where you provide the service dependency with in the constructor.

For example if there is a UserService that needs LoggerService for logging purpose can define the dependency in its constructor as shown below-

@Injectable({
  providedIn: 'root',
})
export class UserService {
  constructor(private loggerService: LoggerService){}
  ..
  ..
}

Call one service from another Angular example

Let’s create a full example to see how to configure dependency for another service. We’ll revisit the example Angular @Input and @Output Example that way we can also show how using service classes reduce the complexity in your application by making the communication among several components easy. You don’t have to rely that much on providing custom property binding through @Input and providing custom event binding through @Output. Service class can act like a centralized class which facilitate communication among Angular components.

In the example user names are displayed and clicking any of these names displays the user details.

Initially user names are displayed.

call one service from another

On clicking name, details are displayed.

Angular service dependency on another service

user.model.ts class

First thing is to define the User class with fields Name, Age, JoinDate.

export class User {
  name : string;
  age : number;
  joinDate : Date;
  constructor(name: string, age : number, joinDate : Date) {
    this.name = name;
    this.age = age;
    this.joinDate  = joinDate;
  }
}

user.component.html

Template for displaying user names.

<div class="row">
  <div class="col-xs-12 col-md-8 px-3">
    <p style="cursor:pointer" 
      class="list-group-item" 
      (click)="onClickUser()">
      {{user.name}}
    </p>
  </div>
</div>

UserComponent class

import { Component, OnInit, Input } from '@angular/core';
import { User } from './user.model';
import { UserService } from '../services/user.service';

@Component({
  selector: 'app-user',
  templateUrl: './user.component.html',
  styleUrls: ['./user.component.css']
})
export class UserComponent implements OnInit {
  @Input() user: User;
  @Input() index: Number;
  constructor(private userService: UserService){}
  ngOnInit(): void {
  }
  onClickUser(){
    this.userService.indexClicked.emit(this.index);
  }
}

As you can see in UserComponent there is an input property binding for user which means it will get user data from another component. In the onClickUser() method it emits the index of the clicked user.

AppComponent class

That’s where user data is fetched from the service and passed on to the UserComponent to display user names.

import { Component, OnInit } from '@angular/core';
import { User } from './user/user.model';
import { UserService } from './services/user.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'], 
})
export class AppComponent implements OnInit{
  users: User[] = [];
  constructor(private userService: UserService){}
  ngOnInit(){
    // get all the users
    this.users = this.userService.users;
  }
}

app.component.html

<div class="container">
  <div class="row">
    <div class="col-md-5">
      <div class="list-group">
        <app-user *ngFor="let u of users; let i = index" [user]="u" [index]="i"></app-user>
      </div>
    </div>
    <div class="col-md-7">
      <appuser-detail></appuser-detail>
    </div>
  </div>
</div>

As you can see in *ngFor directive user array iteration is done and each user is assigned to the [user] property and index is also assigned to the [index] property binding.

UserService class

import { User } from '../user/user.model';
import { EventEmitter, Injectable } from '@angular/core';
import { LoggerService } from './logger.service';

@Injectable({
  providedIn: 'root',
})
export class UserService {
  // dependency on Logger Service
  constructor(private loggerService: LoggerService){}
  // User detail array
  users = [new User('Jack', 62, new Date('2005-03-25')),
  new User('Olivia', 26, new Date('2014-05-09')),
  new User('Manish', 34, new Date('2010-10-21'))] ;
  
  indexClicked = new EventEmitter<Number>();

  getUserDetails(id: Number){
    this.loggerService.log("getting user data for ID- " + id);
    return this.users[id.valueOf()];
  }
}

This is the class that has users stored in the array. There is a property indexClicked of type EventEmitter that emits a number. In the UserComponent class index of the selected user is emitted using this property. Method getUserDetails() returns user instance from the array for the passed index.

UserService has a dependency on LoggerService which is specified in the constructor. In the getUserDetails() method loggerService is used to log a message.

LoggerService class

Though it is better to use @Injectable decorator with provider for LoggerService too, just to show another way of providing service, provider for this service is registered in AppModule.

export class LoggerService {

  constructor() { }
  log(msg: string) { 
    console.log(msg); 
  }
  error(msg: string) { 
    console.error(msg); 
  }
}

AppModule class

@NgModule({
  declarations: [
    AppComponent,
    UserComponent, 
    UserDetailComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule
  ],
  providers: [LoggerService],
  bootstrap: [AppComponent]
})
export class AppModule { }

UserDetailComponent class

This component has the property bindings for showing user details for the selected user.

import { Component, OnInit } from '@angular/core';
import { UserService } from '../services/user.service';
import { User } from './user.model';

@Component({
    selector: 'appuser-detail',
    templateUrl: './userdetail.component.html'
  })
export class UserDetailComponent {
  id: Number;
  user: User;
  constructor(private userService: UserService){
    this.userService.indexClicked.subscribe(
      (index: Number) => {
        this.id = index;
        console.log(this.id);
        this.user = this.userService.getUserDetails(this.id);
      }
    )
  }
}

In the UserService there is a property indexClicked that emits event. In this component we subscribe to that property and get the index. Using that index userService.getUserDetails() method is called by passing the index as argument.

userdetail.component.html

<div *ngIf="user">
  <div class="mt-4 p-5 bg-light">
    <h2>User Details</h2>
    <div class="row">
      <div class="col-xs-5 px-3">
        <label>Name: </label> {{ user.name }}      
      </div>
      <div class="col-xs-4 px-3">
        <label>Age: </label> {{ user.age }}
      </div>
      <div class="col-xs-4 px-3">
        <label>Joining Date: </label> {{ user.joinDate | date:'dd/MM/yyyy'}}
      </div>
    </div>
  </div>
</div>

Here *ngIf directive is used to show the details only when there is user data to be displayed.

That's all for this topic Angular - Call One Service From Another. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Angular Tutorial Page


Related Topics

  1. Injector Hierarchy and Service Instances in Angular
  2. Angular Routing Concepts With Example
  3. Angular Disable Button Example
  4. Angular ngStyle Directive With Examples
  5. Angular Two-Way Data Binding With Examples

You may also like-

  1. Angular Attribute Binding With Examples
  2. Angular Application Bootstrap Process
  3. Nested Route (Child Route) in Angular
  4. Highlight Currently Selected Menu Item Angular Routing Example
  5. CopyOnWriteArrayList in Java
  6. Literals in Java
  7. List in Python With Examples
  8. Spring Transaction Management JDBC Example Using @Transactional Annotation