NashTech Insights

Stateful and Stateless Components in Angular

Alka Vats
Alka Vats
Table of Contents

Introduction:

In Angular development, understanding the concepts of stateful and stateless components is essential for building scalable and maintainable applications. Stateful components handle data management and business logic, while stateless components focus on rendering the user interface based on the provided inputs. In this blog post, we will delve deeper into stateful and stateless components, explore their characteristics, and provide detailed examples to demonstrate their usage in Angular.

If you want to learn about a new feature of angular, you can refer here.

Stateful Components:

Stateful components, also known as container components, are responsible for managing the state of the application. They possess the following characteristics:

a) Maintain Internal State:

Stateful components have their own internal state variables, storing data that is relevant to their functionality. These variables hold information such as form inputs, fetched data from APIs, or any other application-specific data.

Example of a Stateful Component in Angular:

Let’s consider an example of a stateful component that manages a shopping cart in an e-commerce application.

import { Component } from '@angular/core';
import { CartService } from 'path/to/cart.service';

@Component({
  selector: 'app-shopping-cart',
  template: `
    <div *ngFor="let item of cartItems">
      {{ item.name }} - {{ item.price }}
    </div>
    <button (click)="checkout()">Checkout</button>
  `,
})
export class ShoppingCartComponent {
  cartItems: any[];

  constructor(private cartService: CartService) {}

  ngOnInit() {
    this.cartItems = this.cartService.getCartItems();
  }

  checkout() {
    // Perform checkout logic
  }
}

In this example, the ShoppingCartComponent is a stateful component that maintains the state of the shopping cart. It uses the CartService to fetch the cart items and stores them in the cartItems internal state variable. The template displays the cart items using *ngFor and provides a checkout button that triggers the checkout() method.

b) Interact with Services and APIs:

Stateful components communicate with services and APIs to perform operations like data fetching, data manipulation, or making HTTP requests. They encapsulate the business logic of the application and orchestrate the flow of data.

Example of a Stateful Component with Service Interaction:

Let’s consider an example of a stateful component that retrieves user data from an API using a service.

import { Component } from '@angular/core';
import { UserService } from 'path/to/user.service';

@Component({
  selector: 'app-user-list',
  template: `
    <div *ngFor="let user of users">{{ user.name }}</div>
  `,
})
export class UserListComponent {
  users: any[];

  constructor(private userService: UserService) {}

  ngOnInit() {
    this.userService.getUsers().subscribe((data) => {
      this.users = data;
    });
  }
}

In this example, the UserListComponent is a stateful component responsible for retrieving user data from the UserService. It subscribes to the getUsers() method, which returns an observable of user data. When the data is received, it is stored in the users internal state variable, and the template renders the user names using *ngFor.

c) Delegate Data to Child Components:

Stateful components pass down data and behavior to child components using input properties and event emitters. This allows stateful components to manage and control the data flow within the application.

Example of a Stateful Component Delegating Data to Child Components:

Consider a scenario where a stateful component manages a list of products and delegates the product details to a child component for rendering.

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

@Component({
  selector: 'app-product-list',
  template: `
    <app-product-item *ngFor="let product of products" [product]="product" (itemClick)="handleItemClick(product)"></app-product-item>
  `,
})
export class ProductListComponent {
  products: any[];

  constructor(private productService: ProductService) {}

  ngOnInit() {
    this.products = this.productService.getProducts();
  }

  handleItemClick(product: any) {
    // Handle item click logic
  }
}

In this example, the ProductListComponent is a stateful component that retrieves a list of products from the ProductService. It iterates over the products array using *ngFor and passes each product as an input property to the ProductItemComponent. It also listens to the itemClick event emitted by the ProductItemComponent and handles the click event in the handleItemClick() method.

Stateless Components:

Stateless components, also known as presentational components or dumb components, focus on rendering the user interface based on the provided inputs. They possess the following characteristics:

a) Receive Data via Input Properties:

Stateless components accept data from their parent components through input properties, also known as props. They rely on the provided inputs to render the UI and do not manage any internal state.

Example of a Stateless Component in Angular:

Consider an example of a stateless component that renders a product item based on the provided input

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

@Component({
  selector: 'app-product-item',
  template: `
    <div (click)="onItemClick()">
      {{ product.name }} - {{ product.price }}
    </div>
  `,
})
export class ProductItemComponent {
  @Input() product: any;

  onItemClick() {
    // Handle item click logic
  }
}

In this example, the ProductItemComponent is a stateless component that receives a product object as an input property. It renders the product name and price, and when clicked, it triggers the onItemClick() method.

b) Emit Events to Parent Components:

Stateless components raise events using event emitters to notify their parent components about user interactions or changes. The parent components can listen to these events and respond accordingly.

Example of a Stateless Component Emitting Events:

Consider an example of a stateless component representing a button that emits a custom event when clicked.

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

@Component({
  selector: 'app-button',
  template: `
    <button (click)="onClick()">Click Me</button>
  `,
})
export class ButtonComponent {
  @Output() buttonClick = new EventEmitter<void>();

  onClick() {
    this.buttonClick.emit();
  }
}

In this example, the ButtonComponent is a stateless component that emits a buttonClick event when the button is clicked. The parent component can listen to this event and handle it accordingly.

Conclusion:

Understanding the distinction between stateful and stateless components in Angular is crucial for building scalable and maintainable applications. Stateful components manage data, business logic, and user interactions, while stateless components focus on rendering the user interface based on provided inputs. By properly separating these components and adhering to the principles of data and UI separation, developers can achieve cleaner code, better code reusability, and improved maintainability in their Angular projects.

Finally, for more such posts, please follow our LinkedIn page- FrontEnd Competency.

Alka Vats

Alka Vats

Alka Vats is a Software Consultant at Nashtech. She is passionate about web development. She is recognized as a good team player, a dedicated and responsible professional, and a technology enthusiast. She is a quick learner & curious to learn new technologies. Her hobbies include reading books, watching movies, and traveling.

Leave a Comment

Your email address will not be published. Required fields are marked *

Suggested Article

%d bloggers like this: