Day 28 Challenge: Build a Real-Time Chat App with Angular

sunny gsunny g
5 min read

Challenge Overview:

In this challenge, you'll build a real-time chat application using Angular and WebSocket technology to facilitate real-time communication. The goal is to create an app where users can send and receive messages instantly without the need to refresh the page.

You'll integrate Socket.IO to handle real-time communication and build a clean UI with Angular Material. Additionally, you'll manage users, messages, and notifications.

By the end of this challenge, you'll have a functional chat app that supports real-time messaging and showcases how to handle websockets, state management, and UI responsiveness.


Objective:

  1. Set up Angular project and integrate it with Socket.IO for real-time messaging.

  2. Build the chat interface using Angular Material.

  3. Handle WebSocket connections to send and receive messages in real-time.

  4. Implement a user authentication system (optional) to manage user sessions.

  5. Deploy the app and test real-time chat functionality.


Step 1: Set Up Angular Project and Install Dependencies

  1. Create a New Angular Project:

    Start by creating a new Angular application:

     ng new real-time-chat-app
     cd real-time-chat-app
    
  2. Install Required Dependencies:

    You need to install the following dependencies:

    • Socket.IO Client to connect to the server.

    • Angular Material to style the chat app.

Run the following commands to install them:

    npm install socket.io-client
    ng add @angular/material

Choose a theme (e.g., Indigo/Pink) and enable global typography and animations during the Angular Material setup.


Step 2: Set Up WebSocket Server (Backend)

To handle the real-time communication, you need a backend server that uses Socket.IO.

  1. Create a Backend Directory:

    In your project directory, create a server/ folder and set up a basic Node.js server with Express and Socket.IO.

  2. Install Server Dependencies:

    Run the following commands to set up a simple Node.js server:

     npm init -y
     npm install express socket.io
    
  3. Create the Server:

    Inside the server/ folder, create an index.js file:

     // server/index.js
     const express = require('express');
     const http = require('http');
     const socketIo = require('socket.io');
    
     const app = express();
     const server = http.createServer(app);
     const io = socketIo(server);
    
     app.get('/', (req, res) => {
       res.send('Real-time Chat App Server is running');
     });
    
     // Listen for connections
     io.on('connection', (socket) => {
       console.log('a user connected');
    
       // Listen for messages from the client
       socket.on('chat-message', (msg) => {
         console.log('Message received: ' + msg);
         // Broadcast the message to all clients
         io.emit('chat-message', msg);
       });
    
       socket.on('disconnect', () => {
         console.log('user disconnected');
       });
     });
    
     server.listen(3000, () => {
       console.log('Server is listening on port 3000');
     });
    
  4. Run the Server:

    Start the server with:

     node server/index.js
    

    The server will now listen for WebSocket connections on port 3000.


Step 3: Set Up the Frontend (Angular)

  1. Create a Service for WebSocket Communication:

    Create a service in Angular to handle WebSocket connections.

    Run:

     ng generate service services/chat
    

    In chat.service.ts, add the following code:

     import { Injectable } from '@angular/core';
     import { Subject } from 'rxjs';
     import * as io from 'socket.io-client';
    
     @Injectable({
       providedIn: 'root'
     })
     export class ChatService {
       private socket;
       private messageSubject = new Subject<string>();
    
       constructor() {
         this.socket = io('http://localhost:3000');
         this.listenForMessages();
       }
    
       sendMessage(msg: string) {
         this.socket.emit('chat-message', msg);
       }
    
       listenForMessages() {
         this.socket.on('chat-message', (msg: string) => {
           this.messageSubject.next(msg);
         });
       }
    
       get messages$() {
         return this.messageSubject.asObservable();
       }
     }
    

    This service will:

    • Emit messages to the backend via WebSocket.

    • Listen for incoming messages and push them to the Angular component via RxJS Subject.

  2. Create the Chat Component:

    Generate a chat component where the chat interface will be displayed.

    Run:

     ng generate component components/chat
    

    Modify chat.component.ts to interact with the ChatService:

     import { Component, OnInit } from '@angular/core';
     import { ChatService } from '../../services/chat.service';
    
     @Component({
       selector: 'app-chat',
       templateUrl: './chat.component.html',
       styleUrls: ['./chat.component.css']
     })
     export class ChatComponent implements OnInit {
       message = '';
       messages: string[] = [];
    
       constructor(private chatService: ChatService) {}
    
       ngOnInit(): void {
         this.chatService.messages$.subscribe((msg) => {
           this.messages.push(msg);
         });
       }
    
       sendMessage(): void {
         if (this.message.trim()) {
           this.chatService.sendMessage(this.message);
           this.message = ''; // Clear the input field
         }
       }
     }
    
  3. Design the Chat UI:

    Modify chat.component.html to build the chat interface using Angular Material components:

     <div class="chat-container">
       <div class="messages">
         <mat-card *ngFor="let msg of messages" class="message-card">
           <mat-card-content>{{ msg }}</mat-card-content>
         </mat-card>
       </div>
       <mat-form-field class="chat-input">
         <input matInput [(ngModel)]="message" placeholder="Type your message...">
       </mat-form-field>
       <button mat-raised-button color="primary" (click)="sendMessage()">Send</button>
     </div>
    

    Add some styles in chat.component.css:

     .chat-container {
       display: flex;
       flex-direction: column;
       width: 100%;
       height: 100%;
       justify-content: flex-end;
     }
    
     .messages {
       flex: 1;
       overflow-y: auto;
     }
    
     .chat-input {
       display: flex;
       justify-content: space-between;
     }
    
     .message-card {
       margin: 10px;
     }
    

Step 4: Integrate Angular Material

  1. Import Angular Material Modules:

    Open app.module.ts and import the required Angular Material modules:

     import { NgModule } from '@angular/core';
     import { BrowserModule } from '@angular/platform-browser';
     import { FormsModule } from '@angular/forms';
     import { MatButtonModule } from '@angular/material/button';
     import { MatCardModule } from '@angular/material/card';
     import { MatFormFieldModule } from '@angular/material/form-field';
     import { MatInputModule } from '@angular/material/input';
     import { AppComponent } from './app.component';
     import { ChatComponent } from './components/chat/chat.component';
    
     @NgModule({
       declarations: [
         AppComponent,
         ChatComponent
       ],
       imports: [
         BrowserModule,
         FormsModule,
         MatButtonModule,
         MatCardModule,
         MatFormFieldModule,
         MatInputModule
       ],
       providers: [],
       bootstrap: [AppComponent]
     })
     export class AppModule { }
    

Step 5: Testing the Chat Application

  1. Run the Angular App:

    Start the Angular app with:

     ng serve
    
  2. Test the Real-Time Chat:

    Open multiple browser tabs or windows and test if messages are sent and received in real-time. You should see the messages updating instantly across all connected clients without needing to refresh the page.


Step 6: Bonus Features (Optional)

  1. User Authentication:

    • Implement a simple login system (e.g., using JWT or a mock authentication service) to manage users.
  2. Chat Rooms:

    • Allow users to join different chat rooms or channels. You can modify the backend to support multiple namespaces and rooms with Socket.IO.
  3. Message Persistence:

    • Implement a backend database (e.g., MongoDB) to store chat messages and retrieve them when users reconnect.
  4. User Notifications:

    • Add push notifications or in-app notifications for new messages when the user is inactive or offline.

Conclusion

By completing this challenge, you will have:

  • Built a real-time chat app with Angular and Socket.IO.

  • Learned how to manage WebSocket connections in Angular.

  • Designed a real-time messaging interface using Angular Material.

  • Optionally enhanced the app with user authentication, chat rooms, and notifications.

Requirements to Submit:

  1. A fully functional chat app with real-time messaging.

  2. A clean user interface built with Angular Material.

  3. (Optional) Any extra features like chat rooms, notifications, or authentication.

Good luck, and happy coding! ๐Ÿš€

0
Subscribe to my newsletter

Read articles from sunny g directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

sunny g
sunny g