Angular - Singleton Pattern



This Angular tutorial chapter will discuss the Singleton pattern and provide an example with steps that implement the Singleton pattern from scratch in your Angular application.

What is Singleton Pattern in Angular?

In Angular, the singleton pattern is a design pattern having a single instance of a class throughout the entire application and provide the global point of access to it.

This design pattern is useful when you want to share a single resource to the entire application such as without recreating it; such as services.

Singleton Services

In Angular, a singleton service is a class defined with the @Injectable decorator, which marks the class as a service in Angular. It is used to share "common logic", "data", and "functionality" across various components and services.

This angular feature "enhances" the application performance by reusing the existing code for "common logic" rather than defining the logic in multiple places, and it also decreases the redundancy of code.

To use the singleton service in another component within the same application, we need to use Dependency Injection (another design pattern) to inject and use the service.

Advantages of Singleton Service

Following is a list of advantages of a Angular Singleton Service

  • Enhance Application Performance
  • Globally Access
  • Dependency Injection Friendly
  • Resource Management
  • Easy to Share Data

Implementation

Following is a list of "objectives" that you need to follow to implement the "singleton pattern":

Application Setup

Let's create a "new application" using CLI from scratch to implement the singleton pattern (singleton service). This will help you understand the concept better.

Use the steps given below to create a new Angular application:

Step 1: Open the node.js command or code editor (e.g., VS code) terminal and go to your favorite workspace as:

cd /favourite/workspace/ folder_name

Step 2: Install Angular CLI using the following command:

npm install @angular/cli

Step 3: Create a new angular application, myApp as follows:

ng new myApp

Note: Once you hit the above command, it will ask you a few questions and reply with the default answers.

Step 4: Open the app.component.html file remove everything and place the code below:

<h2>Welcome to Angular Singleton Design Pattern</h2>

Step 5: Navigate to your "application directory" as:

cd myApp

Step 6: Run the application to verify it is created successfully:

ng serve

Step 7: Open your preferred browser (e.g., chrome) and navigate to localhost:4200 to see the output:

Singleton Pattern

Create a Singleton Service

In Angular, a service is a class defined with the @Injectable decorator, which identifies it as a service in Angular. Additionally, services are a feature of a mechanism used to share common logic, data, and functionality that can be used across multiple components, directives, and other services.

Services are also used to communicate with servers via RESTful web services.

We will create an Angular service that has a single instance throughout the entire application, which is commonly known as a singleton service (or the singleton pattern).

Step 1: Create a service, myCalc in your angular application as follows:

ng generate service myCalc

Once the above command is executed successfully, you will able to see "two new files" in your Angular application:

Singleton Pattern

Here,

  • The first file, my-calc.service.spec.ts, is a unit testing file (we typically do not make changes in this file).
  • The second file, my-calc.service.ts, is where we write all the "logic" and "functionalities".

Step 2: Open the my-calc.service.ts file and update with the given code below:

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

@Injectable({
  providedIn: 'root'
})
export class MyCalcService {

  constructor() { }

  add(n1: number, n2: number){
    return n1 + n2;
  }

  subtract(n1: number, n2: number){
    return n1 - n2;
  }

  multiply(n1: number, n2: number){
    return n1 * n2;
  }

  divide(n1: number, n2: number){
    return n1 / n2;
  }

}

Here,

  • The @Injectable makes it a service class.
  • The providedIn: 'root', specifies that this service class has root-level access within the application.

Create a Component

Let's create a component, where we will inject our singleton service class via DI to use its functionality which was defined in the "service class".

Step 1: Create a component, Calculator, as follows:

ng generate component Calculator

Step 2: Open the calculator.component.html file and place the code below:

<div class="calc">
<h3>My Calculator</h3>
<form>
<input type="number" placeholder="First number" [(ngModel)]="n1" name="n1">
<input type="number" placeholder="Second number" [(ngModel)]="n2" name="n2">
</form>
<div class="btns">
   <button (click)="add()">Add</button>
   <button (click)="subtract()">Subtarct</button>
   <button (click)="multiply()">Multiply</button>
   <button (click)="divide()">Divide</button>
</div>
<div class="result" *ngIf="result">
    {{result}}
</div>
</div>

Step 3: Open the calculator.component.css file and place the code below:

.calc{
    width: 60%;
    padding: 10px;
    background-color: beige;
    border-radius: 10px;
    font-family: sans-serif;
}
.calc h3{
    text-align: center;
    font-size: 25px;
}
.calc input{
    width: 90%;
    padding: 10px;
    margin: 10px auto;
    display: flex;
    font-size: 20px;
}
.btns{
    width: 90%;
    margin: 10px auto;
}
.btns button{
    padding: 10px 32px;
    border-radius: 5px;
    border: none;
    background-color: green;
    color: white;
    margin: 10px 10px;
    cursor: pointer;
    font-size: 16px;
}
.result{
    text-align: center;
    margin: 20px auto;
    background-color: rgb(200, 210, 206);
    padding: 10px;
    width: 90%;
    border-radius: 5px;
}

Inject Via Dependency Injection

The Dependency Injection (DI) is also a design pattern in Angular used to inject the other "dependencies" into a module or a component rather than creating them individually for each module or component.

Let's inject the singleton service via Dependency Injection (DI) into our myCalc component to use its functionality, as this component requires its dependencies.

Step 1: Open the calculator.component.ts file in your code editor and place the code below:

import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { MyCalcService } from '../my-calc.service';
import { FormsModule } from '@angular/forms';

@Component({
  selector: 'app-calculator',
  standalone: true,
  imports: [CommonModule, FormsModule],
  templateUrl: './calculator.component.html',
  styleUrl: './calculator.component.css'
})
export class CalculatorComponent{
  //injecting service
  constructor(private myservice: MyCalcService){}
  n1: number = 0;
  n2: number = 0;
  result : any = "";

   add(){
    this.result = "Sum is (n1+n2): " + this.myservice.add(this.n1, this.n2);
   }
   subtract(){
    this.result = "Subtraction is(n1-n2): " + this.myservice.subtract(this.n1, this.n2);
   }
   multiply(){
    this.result = "Multiplication is(n1xn2): " + this.myservice.multiply(this.n1, this.n2);
   }
   divide(){
    this.result = "Division is(n1/n2): " + this.myservice.divide(this.n1, this.n2);
   }

}

Step 2: Open the app.component.html file and update it with the code below

<h2>Welcome to Angular Singleton Design Pattern</h2>
<app-calculator></app-calculator>

Step 3: Now run the application using the following command to see the changes:

ng serve

Here is the first expression of the application:

Singleton Pattern

Here, we calculate the "addition" of "two numbers" by clicking on the add button:

Singleton Pattern

Conclusion

The Singleton pattern in Angular is a design pattern for managing shared states, configurations, or data across an application by ensuring a service has a single instance. This pattern is achieved through the Angular dependency injection system, typically by providing the service at the root level.

Advertisements