Monday, November 24, 2025

Signal in Angular With Examples

In this tutorial we'll see what is signal in Angular and how it is a move towards reactive state management by Angular framework.

Signal in Angular

Angular Signals were officially released in Angular 17 and they provide fine-grained control over the changes in the component. Angular Signals optimize DOM changes by providing a fine-grained, reactive system for updating the UI. When a signal's value change, only those components, which are using that signal value, are notified, that allows Angular to update only the affected sections of the DOM making the process of reloading the component faster. This is an optimization over the full change detection cycle where the full component tree is scanned, starting from the root component and moving downwards.

How are signals defined

A signal is a wrapper around a value and it manages its state. When that value changes all the dependent components are notified. Signals can contain any value, from primitives to complex objects.

For example-

const count = signal(0);

You can create a signal by calling the signal function with the signal's initial value.

How to Read a Signal

You can read a value of the signal by calling the signal with parenthesis.

For example- count()

This calls the signal's getter function.

Types of signals in Angular

Angular signals can be of two types-

  1. Writable signals
  2. Read-only signals

Writable signals

You can create a writable signal by calling the signal function with the signal's initial value. This value can be modified later by using set() or update() function.

If you want to provide a new value to a writable signal, you can set it directly using .set()

count.set(5);

If you want to compute a new value using the previous one, then .update() is a better option.

// increment previous count value by 1
count.update(pv => pv + 1)

Read-only signals

Read-only or computed signals derive their value from other signals. These signals are defined using the computed function, you have to specify the derived value logic with in the computed function.

As example, if there is a Product object with properties as id, name, price and quantity and you want to calculate the total price based on the quantity and price of the product.

productSignal = signal<Product>(id:1, name:'Laptop', price:1000, quantity:5));
// Readable signal
totalPrice = computed(() => {
        const product = this.productSignal();
        return product.price * product.quantity;
});

Here totalPrice signal depends on the price and quantity of the product signal. Whenever the price or quantity updates, Angular knows that totalPrice needs to be updated as well.

As the name suggests, you cannot directly assign values to a read-only signal. Trying to do something like this-

totalPrice.set(5000);

results in a compilation error.

Note that read-only signals are both lazily evaluated and memoized (cached). The logic you have written to derive the value of a computed signal does not run to calculate its value until the first time you read that value.

The calculated value is then cached and the same value is returned when needed without recalculating. If you change any value which is used to calculate the read-only signal value then Angular knows that read-only signal's cached value is no longer valid and it calculates the new value when needed the next time.

Angular Signals example

1. In this simple example there is a count signal with initial value as 0. In the template there is a button, click of that button triggers an event to increment the count.

signaldemo.component.ts

import { Component, signal } from "@angular/core";

@Component({
    selector:'app-signaldemo',
    templateUrl: './signaldemo.component.html',
    standalone:false
})
export class SignalDemoComponent{
    count = signal(0);

    increment(){
        this.count.update(count => count+1);
        console.log(this.count);
    }
}

As you can see in the increment() method, count signal is updated.

src\app\signaldemo.component.html
<div>{{count()}}</div>

<button (click)="increment()">Increment</button>

2. This example demonstrates the use of read-only signal. There is a Product object with properties as id, name, price and quantity and you want to calculate the total price based on the quantity and price of the product.

models\product.model.ts

export class Product{
    id: number;
    name: string;
    price: number;
    quantity: number;

    constructor(id: number, name: string, price: number, quantity: number){
        this.id = id;
        this.name = name;
        this.price = price;
        this.quantity = quantity;
    }
}

Above class is used to create Product objects.

singleproduct.component.ts

import { Component, computed, signal } from "@angular/core";
import { Product } from "../models/product.model";

@Component({
  selector:'app-productSingle',
  templateUrl: './singleproduct.component.html',
  standalone:false
})
export class SingleProductComponent{
  productSignal = signal<Product>(new Product(1, 'Laptop', 1000, 1));

  totalPrice = computed(() => {
    const product = this.productSignal();
    return product.price * product.quantity;
  });
  decrementQuantity():void{
    this.productSignal.update((product) => {
      if(product.quantity > 0){
        return {...product, quantity:product.quantity-1};
          
      }else{
        return {...product};
      }
    });
  }

  incrementQuantity(){
    console.log('increment')
    this.productSignal.update((product) => (
        {...product, quantity:product.quantity+1}
    ));
  }

}

Points to note here-

  1. Product object is created as a signal.
  2. There are two methods to decrement or increment the quantity. In both of these methods signal value of the product is updated by decrementing or incrementing the product.quantity.
  3. There is a computed signal, totalPrice whose value is derived by multiplying the product.price and product.quantity.

singleproduct.component.html

<h1>Product List</h1>

<table border="1">
  <thead>
    <tr>
      <th>ID</th>
      <th>Name</th>
      <th>Price</th>
      <th>Quantity</th>
      <th>Total Price</th>
    </tr>
  </thead>
  <tbody>
    <tr>
        <td>{{ productSignal().id }}</td>
        <td>{{ productSignal().name }}</td>
        <td>{{ productSignal().price }}</td>
        <td><button (click)="decrementQuantity()">-</button>{{ productSignal().quantity}}<button (click)="incrementQuantity()">+</button></td>
        <td>{{totalPrice()}}</td>
    </tr>
  </tbody>
  </table>

3. This example builds on the second example by having an array of Product objects and having a computed signal for grand total.

productsignal.component.ts

import { Component, computed, signal } from "@angular/core";
import { Product } from "../models/product.model";

@Component({
  selector:'app-signalproduct',
  templateUrl: './productsignal.component.html',
  standalone:false
})
export class ProductSignalComponent{
  products = signal<Product[]>([
    new Product(1, 'Laptop', 1000, 1),
    new Product(2, 'RAM', 30, 5),
    new Product(3, 'Mouse', 15, 4),
    new Product(4, 'Headphones', 200, 3),
  ]);

  grandTotal = computed(() => {
    return this.products().reduce((sum, product) => {
      const productTotal = product.price * product.quantity;
      return sum + productTotal;
    }, 0);
  });
    
  decrementQuantity(index: number){
    this.products.update(products => {
      if(products[index].quantity > 0){
        products[index].quantity--;
      }
          
      return [...products];
    });
  }

  incrementQuantity(index: number){
    this.products.update(products => {
      products[index].quantity++;                            
      return [...products];
    });
  }
}

Points to note here-

  1. Here we have an array of Product objects.
  2. For incrementing or decrementing quantity, index of the array is passed to the method as parameter. Using that quantity is incremented or decremented for that specific product.
  3. Since signals in Angular use reference equality to decide if something has changed. It is important to keep state of the object or array as immutable. That is why spread operator is used to create a new array object.

productsignal.component.html

<h1>Product List </h1>

<table border="1">
  <thead>
    <tr>
      <th>ID</th>
      <th>Name</th>
      <th>Price</th>
      <th>Quantity</th>
      <th>Total Price</th>
    </tr>
  </thead>
  <tbody>
    @for(product of products(); track product.id; let i = $index){
        <tr>
            <td>{{ product.id }}</td>
            <td>{{ product.name }}</td>
            <td>{{ product.price }}</td>
            <td><button (click)="decrementQuantity(i)">-</button>{{ product.quantity}}<button (click)="incrementQuantity(i)">+</button></td>
            <td>{{ product.price * product.quantity}}</td>
        </tr>
    }
  </tbody>
  <tfoot>
    <tr>
      <td colspan="4"><strong>Grand Total:</strong></td>
      <td><strong>{{ grandTotal() | currency:'USD' }}</strong></td>
    </tr>
  </tfoot>
  </table>
Angular Signal Example

That's all for this topic Signal in Angular 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. @for in Angular With Examples
  2. @if in Angular With Examples
  3. Angular @Component Decorator
  4. What is Client Side Routing in Angular
  5. Angular Application Bootstrap Process

You may also like-

  1. Angular ngFor Directive With Examples
  2. Angular Disable Button Example
  3. Async Pipe in Angular With Examples
  4. Angular Reactive Form Validation Example
  5. intern() Method in Java String
  6. Java Program - Minimum Spanning Tree - Prim's Algorithm
  7. Method Overloading in Python
  8. Spring JdbcTemplate With ResultSetExtractor Example

Java Program - Minimum Spanning Tree - Prim's Algorithm

In this post we'll see how to find a minimum spanning tree for a given weighted, undirected, and connected graph of V vertices and E edges using Prim's algorithm.

Minimum spanning tree

A minimum spanning tree (MST) for a given weighted, undirected graph is the subset of those edges that connect all the vertices together without forming any cycle and also has the minimum possible sum of weight.

Prim's algorithm

In the algorithm MST is built by adding edges one at a time after analysing all the adjacent edges from the vertices which are already part of the MST and choosing the edge with the minimum weight.

Prim's algorithm is termed as a greedy algorithm which starts by adding one vertex as the starting point and then finds the edge with the minimum weight from the adjacent vertices. This edge is added to the MST. Now, the spanning tree consists of two vertices. Analyse all the edges adjacent to already added vertices (ensure edge has one end in the already added vertices and other end in an unselected vertex). Then select the edge with the minimum weight and add it to the MST. Continue the process until all the vertices are added to the minimum spanning tree.

If we have a graph as given below, then let's see how Prim's algorithm tries to find the minimum spanning tree.

Graph

Let's assume that the starting vertex is A then there are 2 edges AB and AC and both have weights as 2. So, we can choose either of them let's say we go with B.

Now the tree we are constructing has two vertices A and B. Next, we need to select any of the edges from A or B which are not yet selected that means from AC, BC and BE. Algorithm choses the edge with minimum weight which is 2 meaning AC.

minimum spanning tree

Tree has three vertices now A, B and C. For next selection our choices are BC, BE, CE and CD. Out of these BC won't be considered because B and C are already added to the tree. Edge with minimum weight is CE with weight as 1.

Prims algorithm Java program

For the last vertex our choices are CD and DE. Out of that DE with weight 6 will be chosen as per Prim's algorithm.

Prim's algorithm with adjacency matrix Java Program

Since edge with minimum weight is required in each analysis of adjacent vertices so min heap created using Priority Queue is one option or you can write the logic yourself to get the minimum weight edge. Here we'll see Java programs for Prim's algorithm using both options.

How does the Prim's algorithm program works

You need three arrays-

The array named edges to store the connected edges for the vertices which are already part of the MST. This array is used to find the edge with minimum weight. Initially this array is initialized with infinite value for all the elements.

The array named mstVertices to store the constructed MST. Initialize it with -1 for all the elements in the array.

A Boolean array isInMST to keep track of the vertices which are already added to the minimum spanning tree.

Prim's algorithm starts by choosing an arbitrary vertex as starting vertex. This starting vertex is added to edges[0]. Then the process follows the following iteration.

While MST doesn't have all the vertices-

1. Find the minimum weight vertex (u), which is not already included in the MST (isInMST[i] == false).

2. Add this vertex to the MST. (add vertex to array mstVertices, set isInMST for this vertex as true)

3. Find all the adjacent vertices from the vertex u. Iterate to check all vertices v adjacent to the current vertex u. If the current edge from u to v is less than the current value of edges[v] , update edges[v] to this new lower weight.

Here is the complete Java program with the logic to create adjacency matrix and then finding the MST using Prim's algorithm.

public class Prims {
  // to store number of vertices in the graph
  private int vertices;
  private int[][] adjMatrix;

  // This array is used to pick the minimum weight edge
  // from the vertices which are not yet included in MST 
  private int[] edges;
  // Array to store the constructed MST
  private int[] mstVertices;
  // Array to check whether vertex is already included or not 
  //(true means vertex is already present)
  private boolean[] isInMST;

      
  Prims(int vertices){
    this.vertices = vertices;
    // matrix having same row and columns as vertices
    adjMatrix = new int[vertices][vertices];
    
    edges = new int[vertices];
    mstVertices = new int[vertices];
    isInMST = new boolean[vertices];
        
    for(int i = 0; i < vertices; i++){
      edges[i] = Integer.MAX_VALUE;
      mstVertices[i] = -1;
    }
    // Add the arbitrary vertex (here taken as 0) from where to 
    // start as the first element
    edges[0] = 0;

  }
  
  //For adding edges to the graph
  public void addEdge(int source, int destination, int weight) {
    if((source < 0 || source > vertices) || (destination < 0 || destination > vertices)) {
      System.out.println("Invalid edge addition");
      return;
    }
    adjMatrix[source][destination] = weight;
    // For undirected graph reverse setting also required
    adjMatrix[destination][source] = weight;
  }
  
  // For printing the adjacency matrix representing the graph
  public void printGraph() {
    for(int i = 0; i < adjMatrix.length; i++) {
      for(int j = 0; j < adjMatrix[0].length; j++) {
        System.out.print(adjMatrix[i][j] + "\t");
      }
      System.out.println();
    }
  }
  
  /** Logic for MST using Prim's start here */
  public int minEdge(){
    int min = Integer.MAX_VALUE;
    int minIndex = -1;

    for(int i = 0; i < vertices; i++){
      if(isInMST[i] == false && edges[i] < min){
        minIndex = i;
        min = edges[i];
      }
    }
    return minIndex;
  }
  
  void primMST() {
    for (int i = 0; i < vertices - 1; i++) {
        
      // Pick the minimum weight vertex
      int u = minEdge();

      isInMST[u] = true;
      
      for(int v = 0; v < vertices; v++){
        if(adjMatrix[u][v] != 0 && isInMST[v] == false 
          && adjMatrix[u][v] < edges[v]){
          edges[v] = adjMatrix[u][v];
          mstVertices[v] = u;
        }
      }
    }
  }
  
  void displayMST(){
    System.out.println("Minimum spanning tree is ");
    System.out.println("Edge \tWeight");
    for (int i = 1; i < vertices; i++){
      System.out.println(mstVertices[i] + " - " + i + "\t"
                         + adjMatrix[mstVertices[i]][i]);
    }
  }
  
  public static void main(String[] args) {
    Prims graph = new Prims(5);        
    graph.addEdge(0, 1, 2);
    graph.addEdge(0, 2, 2);
    graph.addEdge(1, 2, 4);
    graph.addEdge(1, 4, 5);
    graph.addEdge(2, 3, 7);
    graph.addEdge(2, 4, 1);
    graph.addEdge(3, 4, 6);
    graph.printGraph();
    graph.primMST();
    graph.displayMST();
  }
}

Output

0	2	2	0	0	
2	0	4	0	5	
2	4	0	7	1	
0	0	7	0	6	
0	5	1	6	0	
Minimum spanning tree is 
Edge 	Weight
0 - 1	2
0 - 2	2
4 - 3	6
2 - 4	1

Time and space complexity with this approach

In the primMST() method there is an outer loop which runs V times with in that there are two separate for loops, each running V times.

One of the inner for loop is used to select the minimum weight edge from the set of vertices not yet included in the MST. Another loop updates the edges array with the values of the adjacent vertices.

There are two separate V iterations with in the outer loop meaning O(V) + O(V) = O(2V). And there are V such oterations through outer loop so the time complexity is O(V2).

Each of the three arrays used, take O(V) space. So, the space complexity of Prim's algorithm is O(V). Note that space complexity for adjacency matrix is O(V2) if that has to be taken into consideration. In that case space complexity is O(V2).

Logic with PriorityQueue

We can replace logic written in minEdge() method by a PriorityQueue acting as a min heap. That priority queue can provide the edge with the minimum weight.

For that we'll create a class Node with fields vertex and weight and a method to compare weights so that priority queue acts as a min heap.

import java.util.PriorityQueue;

public class PrimsPQ {

  static class Node implements Comparable<Node> {
    int vertex, weight;
    Node(int v, int w) { 
      vertex = v; weight = w; 
    }

    public int compareTo(Node other) {
      return this.weight - other.weight;
    }
  }
  // to store number of vertices in the graph
  private int vertices;
  private int[][] adjMatrix;
  
  // This array is used to pick the minimum weight edge
  // from the vetices which are not yet included in MST 
  private int[] edges;
  // Array to store the constructed MST
  private int[] mstVertices;
  // Array to check whether vertex is already included or not 
  //(true means vertex is already present)
  private boolean[] isInMST;

      
  PrimsPQ(int vertices){
    this.vertices = vertices;
    // matrix having same row and columns as vertices
    adjMatrix = new int[vertices][vertices];
    
    edges = new int[vertices];
    mstVertices = new int[vertices];
    isInMST = new boolean[vertices];
    
    
    for(int i = 0; i < vertices; i++){
      edges[i] = Integer.MAX_VALUE;
      mstVertices[i] = -1;
    }
    // Add the arbitrary vertex (here taken as 0) from where to 
    // start as the first element
    edges[0] = 0;

  }
  //For adding edges to the graph
  public void addEdge(int source, int destination, int weight) {
    if((source < 0 || source > vertices) || (destination < 0 || destination > vertices)) {
      System.out.println("Invalid edge addition");
      return;
    }
    adjMatrix[source][destination] = weight;
    // For undirected graph reverse setting also required
    adjMatrix[destination][source] = weight;
  }
  
  // For printing the adjacency matrix representing the graph
  public void printGraph() {
    for(int i = 0; i < adjMatrix.length; i++) {
      for(int j = 0; j < adjMatrix[0].length; j++) {
        System.out.print(adjMatrix[i][j] + "\t");
      }
      System.out.println();
    }
  }
  
  public void primMST() {
    PriorityQueue<Node> pq = new PriorityQueue<>();
    pq.add(new Node(0, edges[0]));

    while (!pq.isEmpty()) {
      Node node = pq.poll();
      int u = node.vertex;
      isInMST[u] = true;

      for(int v = 0; v < vertices; v++){              
        if(adjMatrix[u][v] != 0 && isInMST[v] == false 
            && adjMatrix[u][v] < edges[v]){
          edges[v] = adjMatrix[u][v];
          pq.add(new Node(v, edges[v]));
          mstVertices[v] = u;
        }
      }
    }

  }
    
  void printMST(){
    System.out.println("Minimum spanning tree is ");
    System.out.println("Edge \tWeight");
    for (int i = 1; i < vertices; i++){
      System.out.println(mstVertices[i] + " - " + i + "\t"
                 + adjMatrix[mstVertices[i]][i]);
    }
  }
    
  public static void main(String[] args) {
    PrimsPQ graph = new PrimsPQ(5);
    graph.addEdge(0, 1, 2);
    graph.addEdge(0, 2, 2);
    graph.addEdge(1, 2, 4);
    graph.addEdge(1, 4, 5);
    graph.addEdge(2, 3, 7);
    graph.addEdge(2, 4, 1);
    graph.addEdge(3, 4, 6);

    graph.printGraph();
    graph.primMST();
    graph.printMST();

  }
}

Output

Output
0	2	2	0	0	
2	0	4	0	5	
2	4	0	7	1	
0	0	7	0	6	
0	5	1	6	0	
Minimum spanning tree is 
Edge 	Weight
0 - 1	2
0 - 2	2
4 - 3	6
2 - 4	1

Time and space complexity with this approach

If priority queue is used with adjacency matrix time complexity is still O(V2). Time to find the minimum edge using priority queue becomes O(log V) because of the heap. But there are still two loops running so the time complexity is O(V2).

Each of the three arrays used, take O(V) space, priority queue also takes O(V) space. So, the space complexity of Prim's algorithm is O(V). Note that space complexity for adjacency matrix is O(V2) if that has to be taken into consideration.

Prim's algorithm with adjacency list Java Program

If you are using adjacency list to represent a graph then with priority queue Prim's algorithm can be implemented as given below.

Keeping Graph creation logic in a separate class to keep the code cleaner.

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Graph {
  
  static class Edge implements Comparable<Edge>{
    int destination;
    int weight;
    Edge(int destination, int weight){
      this.destination = destination;
      this.weight = weight;
    }
    @Override
    public int compareTo(Edge o) {
      // TODO Auto-generated method stub
      return Integer.compare(this.weight, o.weight);
    }
  }
  
  int vertices;
  Map<Integer, List<Edge>> adjList;
  
  Graph(int vertices){
    this.vertices = vertices;
    adjList = new HashMap<>();
  }

  void addEdge(int source, int destination, int weight) {

    adjList.computeIfAbsent(source, k->new ArrayList<>()).add(new Edge(destination, weight));
    // For undirected graph
    adjList.computeIfAbsent(destination, k->new ArrayList<>()).add(new Edge(source, weight));
  }
  
  void printGraph() {
    for(Map.Entry<Integer, List<Graph.Edge>> es :adjList.entrySet()) {
      System.out.print("Vertex " + es.getKey() + " connects to: ");
      List<Edge> list = es.getValue();
      for (Edge e : list) {
        System.out.print("[" + e.destination + " with weight " + e.weight + "] ");
      }
      System.out.println();
    }
  }

}

Prim's algorithm implementation

import java.util.Collections;
import java.util.PriorityQueue;

public class PrimsPQ {

  public void primMST(Graph graph) {
    // This array is used to pick the minimum weight edge
    // from the vetices which are not yet included in MST 
    int[] edges = new int[graph.vertices];
    // Array to store the constructed MST
    int[] mstVertices = new int[graph.vertices];
    // Array to check whether vertex is already included or not 
    //(true means vertex is already present)
    boolean[] isInMST = new boolean[graph.vertices];
    for(int i = 0; i < graph.vertices; i++){
      edges[i] = Integer.MAX_VALUE;
      mstVertices[i] = -1;
    }
    edges[0] = 0;
    PriorityQueue<Graph.Edge> pq = new PriorityQueue<Graph.Edge>();
    pq.add(new Graph.Edge(edges[0], 0));

    while (!pq.isEmpty()) {
      Graph.Edge node = pq.poll();
      int n = node.destination;
      // vertex already added
      if(isInMST[n])
        continue;
    
      isInMST[n] = true;

      for(Graph.Edge next : graph.adjList.getOrDefault(n, Collections.emptyList())) {
        int v = next.destination;
        int weight = next.weight;
        if(isInMST[v] == false && weight < edges[v]){
          edges[v] = weight;
          pq.add(new Graph.Edge(v, edges[v]));
          mstVertices[v] = n;
        }
      }
    }
    for (int i = 1; i < graph.vertices; i++)
      System.out.println(mstVertices[i] + " - " + i + "\t"
                   + edges[i]);

  }

    
  public static void main(String[] args) {
    Graph graph = new Graph(5);
    graph.addEdge(0, 1, 2);
    graph.addEdge(0, 2, 2);
    graph.addEdge(1, 2, 4);
    graph.addEdge(1, 4, 5);
    graph.addEdge(2, 3, 7);
    graph.addEdge(2, 4, 1);
    graph.addEdge(3, 4, 6);
    PrimsPQ prims = new PrimsPQ();
    graph.printGraph();
    prims.primMST(graph);
  }
}

Output

Vertex 1 connects to: [0 with weight 2] [2 with weight 4] [4 with weight 5] 
Vertex 2 connects to: [0 with weight 2] [1 with weight 4] [3 with weight 7] [4 with weight 1] 
Vertex 3 connects to: [2 with weight 7] [4 with weight 6] 
Vertex 4 connects to: [1 with weight 5] [2 with weight 1] [3 with weight 6] 
Edge 	Weight
0 - 1	2
0 - 2	2
4 - 3	6
2 - 4	1

Time and space complexity with this approach

We need to get the minimum weight vertex from the priority queue which is a O(log V) operation. That has to be done for V vertices meaning O(V log V)

We need to scan the adjacent edges for the vertex, if there are E edges then O(E log V) is the time for adding the edges to the priority queue. Thus the time complexity of Prim's algorithm, when using adjacency list and priority queue, is O((V+E)log V).

Each of the three arrays used, take O(V) space, priority queue also takes O(V) space. So, the space complexity of Prim's algorithm is O(V). Note that space complexity for adjacency list is O(V+E) if that has to be taken into consideration then the space complexity becomes O(V + E).

That's all for this topic Java Program - Minimum Spanning Tree - Prim's Algorithm. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Advanced Tutorial Page


Related Topics

  1. Weighted Graph Adjacency Representation - Java Program
  2. Detect Cycle in an Undirected Graph Using BFS - Java Program
  3. Java Program - Depth First Search (DFS) Traversal For Graph
  4. Binary Tree Traversal Using Breadth First Search Java Program
  5. Queue Implementation in Java Using Array

You may also like-

  1. Java Program to Get All DB Schemas
  2. Matrix Addition Java Program
  3. Arrange Non-Negative Integers to Form Largest Number - Java Program
  4. Two Sum - Elements in Array With Given Sum Java Program
  5. matches() Method in Java String
  6. Functional Interfaces in Java
  7. Lazy Initialization in Spring Using lazy-init And @Lazy Annotation
  8. @switch in Angular With Examples

Monday, November 10, 2025

@switch in Angular With Examples

Angular 17 added new control flow statements and loops like @for block, @if block and @switch block. In this post we'll see how to use @switch block in Angular with examples.

@switch block in Angular

If you have a lot of conditions doing equality checks then using @switch case, rather than @if block, provides better readability.

@switch block control flow syntax conditionally renders a content block based on the value of an expression. It displays the content block depending on which @case matches the evaluated expression. It is inspired by switch statement in JavaScript.

Syntax of @switch block in Angular is as given below-

@switch (expression) {
  @case (valueA) {
    //Case A block
  }
  @case (valueB) {
    //Case B block
  }
  @default {
    // Default block
  }
}

@switch (expression): This initiates the switch-case statement, where expression is the value that will be compared against the various cases.

@case (value): Inside the @switch block there can be many @case statements, with each @case specifying a value. If the expression strictly equals a value in a @case, the content within that @case block is rendered.

@default: If none of the @case values match the expression, the content within the @default block is rendered. This is an optional block, if no @default block exists and no @case matches, nothing is displayed.

Note that, @switch does not have a fallthrough, if a @case matches the expression, its content is rendered, and flow comes out of the @switch block without going to any other @case or @default block. You do not need break or return statements.

This new @switch block tries to do away with the verbose structure of the ngSwitch Directive in Angular.

@switch block Angular example

In the example there is a component where an array is initialized and a method that returns the length of the array.

switchdemo.component.ts

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

@Component({
    selector: 'app-switchdemo',
    standalone: true,
    templateUrl: './switchdemo.component.html'
})
export class SwitchdemoComponent {
    numArray: number[];
  
    constructor(){
      this.numArray = [1, 2, 3];
    }
  
    getLength() : number{
      return this.numArray.length;
    }
}

In the template there is a switch block that uses the returned length as an expression and renders a message based on the current length of the array.

switchdemo.component.html

<h2>Switch Demo</h2>

@switch(getLength()){
    @case(0){
        <p>No number is added</p>
    }
    @case(1){
        <p>One number is added</p>
    }
    @case(2){
        <p>Two numbers are added</p>
    }
    @case(3){
        <p>Three numbers are added</p>
    }
    @default{
        <p>More than three numbers are added</p>
    }
}

That's all for this topic @switch in Angular 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. @for in Angular With Examples
  2. How to Use ngFor and ngIf in Same Element in Angular
  3. Angular ngStyle Directive With Examples
  4. Directives in Angular
  5. What is Client Side Routing in Angular

You may also like-

  1. Angular Class Binding With Examples
  2. Angular Two-Way Data Binding With Examples
  3. Pure and Impure Pipes in Angular
  4. CanDeactivate Guard in Angular With Example
  5. Interface Static Methods in Java
  6. Shallow Copy And Deep Copy in Java Object Cloning
  7. Python Program to Find Factorial of a Number
  8. React HelloWorld App - First React App

Thursday, November 6, 2025

@if in Angular With Examples

In this article we'll see how to use @if template syntax in Angular with examples.

@if in Angular

The @if built-in control flow block was introduced in Angular 17, which allows you to conditionally render in Angular templates based on whether the condition is true or false.

This new @if syntax is more concise and intuitive and closer to if-else statement in Javascript. Thus, it is a better alternative than the traditional *ngIf directive in Angular.

With @if, there is also support for @else if and @else statements making the syntax for the full @if block as given below-

@if (condition) {
  <!-- Content to display if the condition is true -->
} @else if (anotherCondition) {
  <!-- Content to display if anotherCondition is true and the first condition is false -->
} @else {
  <!-- Content to display if all preceding conditions are false -->
}

With @if block there is a conditional expression. If the condition evaluates to true, the content within the @if block is rendered in the DOM.

If the condition is false, Angular checks for an @else if block. If an @else if block exists and its anotherCondition is true, its content is rendered.

If @if and @else if (which can occur multiple times) conditions are false, the content within the @else block (if present) is rendered.

If there is only @if block and no @else or @else if blocks are present, the content within the @if block is removed from the DOM, if the condition given with @if is false.

Note that, if you are using *ngIf with standalone component then you need to import either NgIf or CommoModule, whereas @if is a part of the template engine itself, which means it is directly available for use without any explicit imports, which is also an advantage of using @if block in Angular.

@if in Angular example

1. Following example uses @if with @else to show different messages based on whether the loggedIn property is true or false.

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

@Component({
  selector: 'app-ifdemo',
  standalone: true,

  template: `
    @if(loggedIn){
      <p>Welcome back</p>
    }@else {
      <p>Please log in</p>
    }`,
})
export class IfdemoComponent {
  loggedIn: boolean = true;
}

2. Here is another example which uses @if, @else if and @else in Angular.

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

@Component({
  selector: 'app-ifdemo',
  standalone: true,

  template: `
    @if(a > b){
      <p>{{a}} is greater than {{b}}</p>
    }@else if(b > a){
      <p>{{b}} is greater than {{a}}</p>
    }@else {
      <p>{{b}} and {{a}} are equal</p>
    }`,
})
export class IfdemoComponent {
 a = 22;
 b = 20;
}

That's all for this topic @if in Angular 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. @for in Angular With Examples
  2. @switch in Angular With Examples
  3. Angular ngSwitch Directive With Examples
  4. Angular ngIf Directive With Examples
  5. Angular ngStyle Directive With Examples

You may also like-

  1. Angular First App - Hello world Example
  2. Angular Class Binding With Examples
  3. Angular Two-Way Data Binding With Examples
  4. CanDeactivate Guard in Angular With Example
  5. Unmodifiable or Immutable List in Java
  6. Initializer Block in Java
  7. java.lang.UnsupportedClassVersionError - Resolving UnsupportedClassVersionError in Java
  8. Python Program to Display Armstrong Numbers

Wednesday, November 5, 2025

@for in Angular With Examples

In this article we'll see how to use @for block in Angular with examples.

@for in Angular

The @for block in Angular is a built-in control flow syntax used to repeatedly loop and render content in a template for each item in an iterable.

@for control flow statement is added in Angular 17 and provides a cleaner syntax than using the ngFor directive in Angular.

Syntax of @for block

@for (item of items; track item.id) {
  <!-- Content to repeat for each item -->
} @empty {
  <!-- Optional content to display if the collection is empty -->
}

Here item variable is assigned the value of each item in the collection.

The 'items' represents the collection to be iterated over. This collection can be an array, a string, or anything that is iterable.

The value of the track expression should be a unique identifier for each item in the collection for example id property, or a value that uniquely identifies each item. Note that the track expression is required.

@empty: This is an optional block that renders its content only if the items collection is empty.

@for example in Angular

1. Looping a simple array of strings

fordemo.component.ts

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

@Component({
  selector: 'app-fordemo',
  standalone: true,
  imports: [],
  templateUrl: './fordemo.component.html',
  styleUrl: './fordemo.component.css'
})
export class FordemoComponent {
  items = ['Ram', 'CPU', 'Mouse', 'Keyboard'];
}

fordemo.component.html

<ul>
  @for(item of items; track item){
    <li>{{item}}</li>
  }  
</ul>

Then import the component in the AppComponent

import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { FordemoComponent } from "./ControlFlow/fordemo/fordemo.component";

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterOutlet, FordemoComponent],
  templateUrl: './app.component.html',
  styleUrl: './app.component.css'
})
export class AppComponent {
  title = 'myApp';
}

And you are ready to use it in app.component.html

<app-fordemo />

That should give you the output as a list of items

•	Ram
•	CPU
•	Mouse
•	Keyboard

2. Looping an array of objects

fordemo.component.ts

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

@Component({
  selector: 'app-fordemo',
  standalone: true,
  imports: [],
  templateUrl: './fordemo.component.html',
  styleUrl: './fordemo.component.css'
})
export class FordemoComponent {
  products = [
    {id:1, name:'Ram', price:45.67}, 
    {id:2, name:'CPU', price:175.67}, 
    {id:3, name:'Mouse', price:23}, 
    {id:3, name:'Keyboard', price:50}
  ];
}

fordemo.component.html

<ul>
  @for(product of products; track product.id){
    <li>{{product.name}} {{product.price}}</li>
  }
</ul>

As you can see now item.id is used as track expression, which should be unique for each item.

3. @for with $empty

<ul>
  @for(item of items; track $index){
    <li>{{item}}</li>

  }@empty {
    <li>There are no items.</li>
  }
</ul>

In the ts file, if items array is empty

items = [];

then $empty block is rendered.

Why is track expression required

As already mentioned, the track expression is required, omitting it results in "@for loop must have a "track" expression" error.

Providing track expression is crucial for performance optimization. It helps Angular efficiently identify and update DOM elements when the underlying data changes, preventing unnecessary re-rendering of the entire list.

Track expression determines a key used to associate array items with the views in the DOM. Having that clear item identity allows Angular to execute a minimal set of DOM operations as items are added, removed or moved in a collection.

For example, if you are adding a new element to an array of length 100, Angular should be able to identify its id as a new id and just append that new element to the DOM, without having to re-render all the other elements.

Using $index as tracking mechanism

$index is one of the implicit variable available with @for, which provides the index of the current row. This $index can also be used as track expression.

<ul>
  @for(item of items; track $index){
    <li>{{item}}</li>
  }
</ul>

track $index should only be preferred as tracking mechanism if collection which is iterated is static. For dynamic collections with frequent additions, deletions, or reordering, opt for a unique property of each item as the tracking key.

Contextual variables available with @for

Within the @for block, you can access several built-in contextual variables using a let expression, such as:

  1. $count- Number of items in a collection iterated over
  2. $index- Index of the current row
  3. $first- Whether the current row is the first row
  4. $last- Whether the current row is the last row
  5. $even- Whether the current row index is even
  6. $odd- Whether the current row index is odd

@for with $index example

Template code

@for(product of products; track product.id; let idx = $index){
    <p>Product #{{ idx+1 }}: {{product.name}} {{product.price}}</p> 
}

If you call it with the following array in .ts file

  products = [
    {id:1, name:'Ram', price:45.67}, 
    {id:2, name:'CPU', price:175.67}, 
    {id:3, name:'Mouse', price:23}, 
    {id:3, name:'Keyboard', price:50}
  ];

Then the output is

Product #1: Ram 45.67
Product #2: CPU 175.67
Product #3: Mouse 23
Product #4: Keyboard 50
Note that index is zero based. 

@for with $odd and $even example

If you want to render a table with odd and even rows in different colours then that can be done using the $odd or $even implicit variable.

fordemo.component.html

<h2>Product Details</h2>
<table border="1">
  <tr>
    <th>S. No</th>
    <th>Id</th>
    <th>Name</th>
    <th>Price</th>
  </tr>
  @for(product of products; track product.id; let idx = $index; let odd = $odd){
    <tr [class.bg]="!odd">
        <td>{{idx+1}}</td>
        <td>{{product.id}}</td>
        <td>{{product.name}}</td>
        <td>{{product.price}}</td>
    </tr>
    
    }
</table>

Note that, class binding in Angular is used here to bind CSS class. The variable odd returns true or false based on whether the row position is even or odd.

fordemo.component.css

.bg{
    background-color: yellow;  
}

fordemo.component.ts

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

@Component({
  selector: 'app-fordemo',
  standalone: true,
  imports: [],
  templateUrl: './fordemo.component.html',
  styleUrl: './fordemo.component.css'
})
export class FordemoComponent {
  products = [
    {id:1, name:'Ram', price:45.67}, 
    {id:2, name:'CPU', price:175.67}, 
    {id:3, name:'Mouse', price:23}, 
    {id:3, name:'Keyboard', price:50}
  ];
}
@for in Angular

That's all for this topic @for in Angular 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. @if in Angular With Examples
  2. @switch in Angular With Examples
  3. Angular ngSwitch Directive With Examples
  4. Angular ngIf Directive With Examples
  5. Angular ngStyle Directive With Examples

You may also like-

  1. How to Create a Custom Attribute Directive in Angular
  2. Passing Query Parameters in Angular Routing
  3. Radio Button in Angular Form Example
  4. Angular @Input and @Output Example
  5. Spring MVC @PathVariable Example - Creating Dynamic URL
  6. Java Collections Interview Questions And Answers
  7. Controlled and Uncontrolled Components in React
  8. Interface in Python

Friday, October 31, 2025

Varargs (Variable-length Arguments) in Java

varargs in Java, short for variable-length arguments is a feature that allows the method to accept variable number of arguments (zero or more). With varargs it has become simple to create methods that need to take a variable number of arguments. The feature of variable argument (varargs) has been added in Java 5.


Syntax of varargs

A vararg in Java is specified by three ellipsis (three dots) after the data type, its general form is

return_type method_name(data_type ... variableName){
 ..
 ..
}  

Python String isnumeric() Method

The isnumeric() method in Python String class is used to check if all the characters in the string are numeric characters or not.

isnumeric() method returns true if all characters in the string are numeric characters and there is at least one character, false otherwise. Numeric characters include digits (0..9) and all characters that have the Unicode numeric value property like superscripts or subscripts (as example 26 and 42), fractions like ¼.

Note that numbers with negative sign like '-123' and with decimal sign like '56.78' are not considered as numbers by isnumeric() method. Same way number in exponential notation like '1.23E+10' is also not considered number.

Python isnumeric method examples

1. Using isnumeric() method to check if all the characters are digits or not.

str = '345'
print(str)
print(str.isnumeric())

str = 'A12B'
print(str)
print(str.isnumeric())

Output

345
True
A12B
False

2. Using isnumeric() method with negative, decimal numbers. For such strings isnumeric() method returns false.

  
  str = '-123'
print(str)
print(str.isnumeric())

str = '45.67'
print(str)
print(str.isnumeric())

str = '1.23E+10'
print(str)
print(str.isnumeric())

Output

-123
False
45.67
False
1.23E+10
False

3. Using isnumeric() method with superscripts or subscripts. For such strings isnumeric() method returns true.

str = '2\u2076'
print(str)
print(str.isnumeric())

str = '4\u2082'
print(str)
print(str.isnumeric())

Output

26
True
42
True

4. Using isnumeric() method with characters that have Unicode numeric value property.

s = '\u246D' #CIRCLED NUMBER FOURTEEN ?
print(s)
print(s.isnumeric())

s = '\u2474' #PARENTHESIZED DIGIT ONE ?
print(s)
print(s.isnumeric())

s = '\u248C' # DIGIT FIVE FULL STOP ?
print(s)
print(s.isnumeric())

s = '\u24B0' #PARENTHESIZED LATIN SMALL LETTER U ?
print(s)
print(s.isnumeric())

Output

⑭
True
⑴
True
⒌
True
⒰
False

That's all for this topic Python String isnumeric() Method. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Python Tutorial Page


Related Topics

  1. Python String isdigit() Method
  2. Changing String Case in Python
  3. Local, Nonlocal And Global Variables in Python
  4. Abstract Class in Python
  5. Global Keyword in Python With Examples

You may also like-

  1. Python assert Statement
  2. Interface in Python
  3. Python Exception Handling - try,except,finally
  4. Convert String to int in Python
  5. Java Multithreading Tutorial
  6. String in Java Tutorial
  7. Spring Web MVC Tutorial
  8. Spring Web Reactive Framework - Spring WebFlux Tutorial