Tuesday, March 19, 2024

Executor And ExecutorService in Java With Examples

This post gives an overview of Java Executors framework in Java which comprises-

  1. Executor interfaces- Executor, ExecutorService and ScheduledExecutorService interfaces which define the three executor object types.
  2. Thread pools- Executor implementation classes like ThreadPoolExecutor and ScheduledThreadPoolExecutor which use thread pools.
  3. Fork/Join- A framework (from JDK 7) for taking advantage of multiple processors.

Thread management through executors in Java

In large-scale applications, its good to separate thread management and creation from the rest of the application. The concurrent API in Java has a feature called Executors that provides an alternative to managing threads through the Thread class.

Executor interface in Java

At the core of the Java executors framework is the Executor interface, which also has two sub interfaces ExecutorService and ScheduledExecutorService.

An object of type Executor can execute runnable tasks. An Executor is normally used instead of explicitly creating threads. For example If r is a Runnable object, and e is an Executor object you can replace

(new Thread(r)).start();
with
e.execute(r);

Methods in Java Executor interface

The Executor interface in Java provides a single method execute().

void execute(Runnable command)- Executes the given command at some time in the future. The command may execute in a new thread, in a pooled thread, or in the calling thread, at the discretion of the Executor implementation.

Java ExecutorService interface

ExecutorService interface in Java extends Executor interface and provides methods to manage termination (through shutdown() method) and methods that can produce a Future (using submit() with a Callable) for tracking progress of one or more asynchronous tasks.

ExecutorService interface has more versatile submit() method. Like execute, submit accepts Runnable objects, but also accepts Callable objects, which allows the task to return a value. The submit method returns a Future object, which is used to retrieve the Callable return value and to manage the status of both Callable and Runnable tasks.

ExecutorService Implementing classes

In the Java concurrency there are three pre-defined executor classes that implement the Executor and ExecutorService interfaces.

  1. ThreadPoolExecutor- Implements the Executor and ExecutorService interfaces and executes the submitted task using one of the pooled thread.
  2. ScheduledThreadPoolExecutor- It extends ThreadPoolExecutor and also implements the ScheduledExecutorService interface. This class schedule commands to run after a given delay, or to execute periodically.
  3. ForkJoinPool implements the Executor and ExecutorService interfaces and is used by the Fork/Join Framework.

Before writing any examples for Executor or ExecutorService, two things are worth knowing Executors class and ThreadPools.

ThreadPools in Java

In a large scale application if each task uses its own thread then allocating and deallocating many thread objects creates a significant memory management overhead.

Thread pool as the name suggests provides a set of threads, any task which has to be executed get a thread from this pool.

Executors class in Java

Executors class provides factory and utility methods for Executors framework classes like Executor, ExecutorService, ScheduledExecutorService, ThreadFactory, and Callable.

Though you can use ThreadPoolExecutor and ScheduledThreadPoolExecutor directly, but the best way to get an executor is to use one of the static factory methods provided by the Executors utility class.

Some of the factory methods provided by Java Executors class are-

  1. static ExecutorService newCachedThreadPool()- Creates a thread pool that creates new threads as needed, but will reuse previously constructed threads when they are available.
  2. static ExecutorService newFixedThreadPool(int numThreads)- Creates a thread pool that reuses a fixed number of threads.
  3. static ScheduledExecutorService newScheduledThreadPool(int numThreads)- Creates a thread pool that can schedule commands to run after a given delay, or to execute periodically.
  4. newSingleThreadExecutor()- Creates an Executor that uses a single worker thread operating off an unbounded queue.

Java ExecutorService Examples

As already mentioned apart from execute() method, ExecutorService also has submit() method which is overloaded to take either Runnable or Callable as parameter. So let's see examples for these methods.

Using execute method

In this ExecutorService example a thread pool of two threads is created, and 6 runnable tasks are executed using execute() method. These 6 tasks will be executed using only these 2 threads from the thread pool, new thread won't be created for each of the 6 tasks. It can be verified from the thread name in the output.

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ExecutorDemo {
 public static void main(String args[]) {
  // creating executor with pool of 2 threads
  ExecutorService ex = Executors.newFixedThreadPool(2);
  // running 6 tasks
  ex.execute(new Task());
  ex.execute(new Task());
  ex.execute(new Task());
  ex.execute(new Task());
  ex.execute(new Task());
  ex.execute(new Task());
  //shutting down the executor service
  ex.shutdown();
 }
}
 
/**
 *
 */
class Task implements Runnable{
 @Override
 public void run() {
  System.out.println("in run task for thread - " + Thread.currentThread().getName());
  // Introducing some delay for switching
  try {
   Thread.sleep(500);
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
}

Output

in run task for thread - pool-1-thread-2
in run task for thread - pool-1-thread-1
in run task for thread - pool-1-thread-1
in run task for thread - pool-1-thread-2
in run task for thread - pool-1-thread-2
in run task for thread - pool-1-thread-1

Submit with Runnable parameter example

In this ExecutorService Java example submit method is used to submit a runnable task for execution which returns a Future representing that task. The Future's get() method will return null upon successful completion of a runnable task.

In the example 2 runnable tasks are submitted which return future objects, in case of Runnable, Future's get method will return null.

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class ExecutorServiceDemo {
 public static void main(String args[]) {
  // creating executor with pool of 2 threads
  ExecutorService ex = Executors.newFixedThreadPool(2);
  // running tasks
  Future f1 = ex.submit(new Task());
  Future f2 = ex.submit(new Task());
  try {
   // getting the future value
   System.out.println("Future f1 " + f1.get());
   System.out.println("Future f1 " + f1.get());
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (ExecutionException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  ex.shutdown();
 }
}

/**
 * Runnable 
 */
class Task implements Runnable{

 @Override
 public void run(){
  System.out.println("in run task for thread - " + Thread.currentThread().getName());
  // Introducing some delay for switching
  try {
   Thread.sleep(500);
  } catch (InterruptedException e) {
   e.printStackTrace();  
  }
 }
}

Output

in run task for thread - pool-1-thread-2
in run task for thread - pool-1-thread-1
Future f1 null
Future f1 null

Submit with Callable as parameter example

In this ExecutorService Java example callable task is submitted using submit() method.

Callable interface has call method which can return value too, so in this case when Future's get method is called it'll return a value. Note that here callable is implemented as a lambda expression.

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class ExecutorServiceDemo {
  public static void main(String args[]) {
    // creating executor with pool of 2 threads
    ExecutorService ex = Executors.newFixedThreadPool(2);
    // Callable implemented as lambda
    Callable<String> c = ()->"Callable lambda is called";
    // running tasks with callable as param
    Future f1 = ex.submit(c);
    try {
      // getting the future value
      System.out.println("Future f1 " + f1.get());
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (ExecutionException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    ex.shutdown();      
  }
}

Output

Future f1 Callable lambda is called

Refer Callable and Future in Java concurrency to know more about Callable and Future in Java concurrency.

ExecutorService shutdown

An ExecutorService can be shut down, which will cause it to reject new tasks. Two different methods are provided for shutting down an ExecutorService. The shutdown() method will allow previously submitted tasks to execute before terminating, while the shutdownNow() method prevents waiting tasks from starting and attempts to stop currently executing tasks. Upon termination, an executor has no tasks actively executing, no tasks awaiting execution, and no new tasks can be submitted. An unused ExecutorService should be shut down to allow reclamation of its resources.

ScheduledExecutorService interface in Java

ScheduledExecutorService extends ExecutorService and provides methods that can schedule commands to run after a given delay, or to execute periodically.

It has methods that execute a Runnable or Callable task after a specified delay.

  • schedule(Callable<V> callable, long delay, TimeUnit unit) - Creates and executes a ScheduledFuture that becomes enabled after the given delay.
  • schedule(Runnable command, long delay, TimeUnit unit) - Creates and executes a one-shot action that becomes enabled after the given delay.

In addition, the interface defines scheduleAtFixedRate and scheduleWithFixedDelay, which executes specified tasks repeatedly, at defined intervals.

  • scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) - Creates and executes a periodic action that becomes enabled first after the given initial delay, and subsequently with the given period; that is executions will commence after initialDelay then initialDelay+period, then initialDelay + 2 * period, and so on.
  • scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) - Creates and executes a periodic action that becomes enabled first after the given initial delay, and subsequently with the given delay between the termination of one execution and the commencement of the next.

ScheduledThreadPoolExecutor Java Example code

In this ScheduledExecutorService Java example callable task is submitted using schedule method which will be executed after a delay of 2 Sec.

import java.util.Date;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

public class STEDemo {
  public static void main(String[] args) {
    ScheduledExecutorService scheduledExecutor = Executors.newScheduledThreadPool(2);
    // Callable implemented as lambda
    Callable<String> c = ()->{
      System.out.println("Time of execution- " + new Date());
      return "Callable lambda is called";
    };
    System.out.println("Time before execution- " + new Date());
    // scheduling tasks with callable as param
    // it will execute after a delay of 2 Secs
    ScheduledFuture<String> sf = scheduledExecutor.schedule(c, 2, TimeUnit.SECONDS); 
    try {
      System.out.println("Value- " + sf.get());
    } catch (InterruptedException | ExecutionException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    scheduledExecutor.shutdown();
  }
}

Output

Time before execution- Wed Nov 21 11:37:15 IST 2018
Time of execution- Wed Nov 21 11:37:17 IST 2018
Value- Callable lambda is called

That's all for this topic Executor And ExecutorService in Java With Examples. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Callable And Future in Java Concurrency
  2. Java ArrayBlockingQueue With Examples
  3. CopyOnWriteArrayList in Java With Examples
  4. Java CyclicBarrier With Examples
  5. Java Concurrency Interview Questions And Answers

You may also like-

  1. How to Iterate a HashMap of ArrayLists of String in Java
  2. How to sort HashSet in Java
  3. Difference Between Comparable and Comparator in Java
  4. Difference Between Checked And Unchecked Exceptions in Java
  5. static Reference to The Non-static Method or Field Error
  6. Race condition in Java multi-threading
  7. Interface Default Methods in Java
  8. Java ThreadLocal Class With Examples

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

Angular Style Binding With Examples

In this post we’ll discuss another one-way binding known as Angular style binding. Using style binding you can set styles dynamically by getting the value of style property conditionally or through a component's property.


Angular style binding syntax

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

[style.style-property] = "style-value"

Here style-property which is the binding target will be set to the value of the bound expression, "style-value" in this case.

For example following statement sets the text color of the button based on the value it receives from the buttonColor variable of the component.

<button [style.color]="buttonColor">Submit</button>

Adding unit extension

You can add a unit extension like em, px or % along with CSS style property or with style-value. For example in the following statement font size for the button is set in px unit.

<button class="btn btn-primary" [style.fontSize.px]="fontSize">Submit</button>

Syntax for multiple styles

You can also add multiple style properties. The expression attached to the [style] binding can be passed as a string list of styles like "width: 100px; height: 100px;".

For example- <button [style]="buttonStyle">Submit</button>

Where buttonStyle is a String variable defined in the component as-

buttonStyle : String ='background-color: #4CAF50; font-size:15px; border: none; color: white';

Angular style binding example

In the component there are two properties textFont and textStyle which will be used for setting CSS style properties in the HTML element.

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

@Component({
  selector: 'app-stylebinding',
  templateUrl: './stylebinding.component.html',
})
export class StylebindingComponent {
  userName: string = "Jack";
  textFont: number = 25;
  textStyle: string ='background-color: #4CAF50; color: white';
}

Template

<div>
    User name is <span [style.fontSize.px]="textFont" [style]="textStyle">{{userName}}</span> 
</div>

In the template span element is styled using the style binding. Using [style.fontSize.px] single property is set which also has a unit extension. Using [style]="textStyle" multiple properties are set. Note that font size can also be include with in the multiple properties, done separately here just to demonstrate how to set both single as well as multiple style properties.

Angular Style Binding

Style binding or ngStyle directive

The NgStyle directive can be used as an alternative to direct [style] bindings but as per Angular documentation style binding is preferred.

“However, using the above style binding syntax without NgStyle is preferred because due to improvements in style binding in Angular, NgStyle no longer provides significant value, and might eventually be removed in the future.”

Reference- https://angular.io/guide/template-syntax#style-binding

That's all for this topic Angular Style 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 Event Binding With Examples
  2. Angular Class Binding With Examples
  3. Angular Two-Way Data Binding With Examples
  4. Angular Custom Event Binding Using @Output Decorator
  5. Angular ngIf Directive With Examples

You may also like-

  1. Angular @Component Decorator
  2. Angular Attribute Binding With Examples
  3. Angular Project Structure With File Description
  4. Injector Hierarchy and Service Instances in Angular
  5. Unmodifiable or Immutable Map in Java
  6. Heap Memory Allocation in Java
  7. Spring MVC File Download Example
  8. Constructor in Python - __init__() function

Saturday, March 16, 2024

Angular Attribute Binding With Examples

In the post Angular Property Data Binding we saw how property binding is done to the corresponding object’s property in the DOM, not to the attribute of the element. Not all HTML element attributes have equivalent properties in the DOM. For such scenario, Angular provides the attribute binding, which sets the value of an attribute on the host element rather than setting the value of the property in the object that represents element in the DOM.

Attribute binding is also type of Angular one-way data binding which is unidirectional. Using attribute binding you can bind data from the component to the view.

Angular One-Way Data Binding

Consider the ARIA and SVG. They are purely attributes, don't correspond to element properties, and don't set element properties. In these cases, there are no property targets to bind to.

<button [attr.aria-label]="buttonAction">{{buttonAction}}</button>

Here ARIA is adding extra label to the button that is only exposed to assistive technology APIs. Anybody using the screen reader will hear the button name as bound to the [attr.aria-label] using Angular attribute binding.

Angular attribute binding example

In the example we’ll use a User model with fields as Name and Age. Let’s take a scenario where you get an array of User objects which you have to display in a table.

You want the colspan attribute of the <td> to be changed as per the length of the user.name. If any of the name’s length is more than 15 then you want colspan to be set to 2 otherwise 1.

user.model.ts

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

user.component.ts

import { 
    Component
 } from '@angular/core';
import { User } from './user.model';
@Component({
  selector: 'app-user',
  templateUrl: './user.component.html'
})
export class UserComponent {
  users: User[];
  columnSpan = 1;
  constructor(){
    // Initializing User instance
    // Adding user instances in the users array
    this.users = [new User('Jack Ryan', 56),
                  new User('Lisa Ray', 32),
                  new User('Abhinav M', 28)] ;
    this.assignColumenLength();
  }
  // Method to get the colspan value
  assignColumenLength(){
    for(let user of this.users){
      if(user.name.length > 15){
        this.columnSpan = 2;
        break;
      }
    }
  }
}

In the component class User model class is imported and an Array of type User is initialized with some user instances.

In the method assignColumenLength() users array is iterated to check if any of the user name has length more than 15 if yes then columnspan property is set as 2.

user.component.html

<div class="container">
  <h2>User Details</h2>
  <table class="table table-sm table-bordered m-t-4">
    <tr>
      <th [attr.colspan]="columnSpan">Name</th>
      <th>Age</th>
    </tr>
    <tr *ngFor="let user of users">
      <td [attr.colspan]="columnSpan">{{user.name}}</td>
      <td>{{user.age}}</td>
    </tr>
  </table>
</div>

app.component.html

In app.component.html we just need to add the <app-user> tag.

<app-user></app-user>

After running the application if you inspect the element you can see that the colspan attribute has value 1 as no name has length more than 15.

attribute binding

Now change the users array as given below-

this.users = [new User('Jack Ryan', 56),
              new User('Lisa Ray', 32),
              new User('Abhinav Mukhopadyaya', 28)] ;

After running the application if you inspect the element now, you can see that the colspan attribute has value 2 as one of the name has length more than 15.

attribute binding angular

That's all for this topic Angular Attribute 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 One-Way Data Binding Using String Interpolation
  2. Angular Style Binding With Examples
  3. Angular Event Binding With Examples
  4. Angular Class Binding With Examples
  5. Angular Custom Two-Way Data Binding

You may also like-

  1. Angular Reactive Form Example
  2. Angular Disable Button Example
  3. Angular ngFor Directive With Examples
  4. Angular Application Bootstrap Process
  5. Just In Time Compiler (JIT) in Java
  6. Dependency Injection in Spring Framework
  7. Transaction Management in Spring
  8. Installing Anaconda Distribution On Windows

Friday, March 15, 2024

Angular One-Way Data Binding Using String Interpolation

In this article we’ll see how to do Angular one way data binding using string interpolation. As the name itself suggests Angular one-way binding is unidirectional and using String interpolation you can bind data from the component to the view.

Angular One-Way Data Binding

String interpolation – Angular data binding

The string interpolation binding is specified using pairs of curly braces {{ property/expression }}. The property or expression given in between the curly braces is evaluated and resolved to its value.

String interpolation expression can be:

  • property {{ message }} or {{ user.name }}
  • expression {{7 + (8/4)}}
  • method call {{getData()}}
  • String {{‘Hello ’ + ‘World’}}

Angular String Interpolation One-way data binding example

In the example we’ll use a User model with fields as Name and Age. Using String interpolation binding, values of these fields are displayed in the HTML.

user.model.ts

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

user.component.ts

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

UserComponent uses User model so that is imported. In the Constructor an instance of User is created. There is also a message property with value assigned to it.

In a real application you may get the User data using http request from some backing application but here it is hard coded.

user.component.html

<div class="container">
  <div class="row">    
    <div class="col-xs-10">
      <h3>{{ message }}</h3>
    </div> 
  </div>
  <div class="row">
    <div class="col-xs-6">
      <label>Name: </label> {{ user.name }}
    </div>
  </div> 
  <div class="row">
    <div class="col-xs-6">
      <label>Age: </label> {{ user.age }}
    </div>
  </div>
</div>

Note that in the template, Bootstrap is used for styling. Refer this post to see how to include Bootstrap in your Angular application- How to Add Bootstrap to Angular Application

app.component.html

In app.component.html we just need to add the <app-user> tag.

<app-user></app-user>

As you can see here value for message property as well as for user.name and user.age is derived using String interpolation data binding.

One thing to note here is that value you get by String interpolation is always of type String. So user.age which is of type number is internally converted to String.

Angular String Interpolation Binding

Calling a method using Angular One-way data binding

As mentioned above you can also call a method in between the curly braces and also use a String. To demonstrate that let’s remove message property and add a method getMessage() in the component.

export class UserComponent {
  user: User;
  constructor(){
    this.user = new User('Jack', 56);
  }

  getMessage(){
    return 'User Details';
  }
}
And the corresponding changes in the template to get the message by calling method.
<h3>{{ getMessage() }}</h3>

Also notice the <label>{{'Name:'}} </label> showing how you can use String interpolation with String value.

<div class="container">
  <div class="row">    
    <div class="col-xs-10">
      <h3>{{ getMessage() }}</h3>
    </div> 
  </div>
  <div class="row">
    <div class="col-xs-6">
      <label>{{'Name:'}} </label> {{ user.name }}
    </div>
  </div> 
  <div class="row">
    <div class="col-xs-6">
      <label>Age: </label> {{ user.age }}
    </div>
  </div>
</div>

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

>>>Return to Angular Tutorial Page


Related Topics

  1. Angular Two-Way Data Binding With Examples
  2. Angular Custom Property Binding Using @Input Decorator
  3. Angular Custom Event Binding Using @Output Decorator
  4. Angular Property Binding With Examples
  5. Service in Angular With Examples

You may also like-

  1. Angular Project Structure With File Description
  2. Angular ngClass Directive With Examples
  3. Angular @Input and @Output Example
  4. Angular Disable Button Example
  5. Just In Time Compiler (JIT) in Java
  6. Dependency Injection in Spring Framework
  7. Transaction Management in Spring
  8. Installing Anaconda Distribution On Windows

Angular Template-Driven Form Validation Example

In the post Angular Template-Driven Form Example we saw an example of creating a simple template-driven form in Angular but that example lacked one important aspect of forms; validations. In this post we’ll see an example of Angular template-driven form with validations.

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.