Real Time Connections page

Updating Order History View with Real Time Connection

Overview

In this part, we will:

  • Install socket.io Client
  • Update list view on socket events.

P1: How to verify your solution is correct

If you’ve implemented the solution correctly you should now be able to navigate to http://localhost:4200/order-history and see orders be created, updated or removed without refreshing the page!

Install Socket.io Client and Types

npm install socket.io-client@2
npm install --save-dev @types/socket.io-client@1

Listen to Socket Events

We’ll use apiUrl for our Socket.io connection, and listen for orders created, order updated, and orders deleted events to change our list on:

✏️ Update src/app/order/history.component.ts

import { Component, OnDestroy, OnInit } from '@angular/core';
import { Subject, takeUntil } from 'rxjs';
import io from 'socket.io-client';
import { ResponseData } from '../../restaurant/restaurant.service';
import { environment } from '../../../environments/environment';
import { Order, OrderService } from '../order.service';

interface Data<T> {
  value: T[];
  isPending: boolean;
}

@Component({
  selector: 'pmo-history',
  templateUrl: './history.component.html',
  styleUrl: './history.component.css',
})
export class HistoryComponent implements OnInit, OnDestroy {
  orders: Data<Order> = { value: [], isPending: true };
  private onDestroy$ = new Subject<void>();
  socket: SocketIOClient.Socket;

  constructor(private orderService: OrderService) {
    this.socket = io(environment.apiUrl);
  }

  ngOnInit(): void {
    this.getOrders();

    this.socket.on('orders created', (order: Order) => {
      this.orders.value.push(order);
    });

    this.socket.on('orders updated', (order: Order) => {
      const orderIndex = this.orders.value.findIndex(
        (item) => item._id === order._id
      );
      this.orders.value.splice(orderIndex, 1);
      this.orders.value.push(order);
    });

    this.socket.on('orders removed', (order: Order) => {
      const orderIndex = this.orders.value.findIndex(
        (item) => item._id === order._id
      );
      this.orders.value.splice(orderIndex, 1);
    });
  }

  ngOnDestroy(): void {
    this.socket.removeAllListeners();
    this.onDestroy$.next();
    this.onDestroy$.complete();
  }

  getOrders(): void {
    this.orderService
      .getOrders()
      .pipe(takeUntil(this.onDestroy$))
      .subscribe((res: ResponseData<Order>) => {
        this.orders.value = res.data;
      });
  }

  get newOrders(): Order[] {
    const orders = this.orders.value.filter((order) => {
      return order.status === 'new';
    });
    return orders;
  }

  get preparingOrders(): Order[] {
    const orders = this.orders.value.filter((order) => {
      return order.status === 'preparing';
    });
    return orders;
  }

  get deliveryOrders(): Order[] {
    const orders = this.orders.value.filter((order) => {
      return order.status === 'delivery';
    });
    return orders;
  }

  get deliveredOrders(): Order[] {
    const orders = this.orders.value.filter((order) => {
      return order.status === 'delivered';
    });
    return orders;
  }
}

Now as we create, update, and delete orders we can see them updated in real time across different browser tab instances!