Challenges with Socket.IO Integration in Angular
Published: 2024-03-01 20:19:49

I'm experiencing difficulties integrating Socket.IO into my Angular application. Specifically, when attempting to load a component route that includes Socket.IO service integration, the route fails to load properly. Despite correctly configuring the Socket.IO service within the component and verifying that the server is emitting messages, the component fails to render, leaving me unable to display server messages or interact with the component as expected.


## Server Configuration (server.ts)


In the backend, I've set up a Socket.IO server that emits a welcome message to newly connected clients and listens for disconnect events.

```
import express from "express";
import { Server as SocketIOServer } from 'socket.io';
import http from "http";
import cors from "cors";
import {sample_games} from "./data";
import RestGames from './services/rest/restGames';

const app = express();
const server = http.createServer(app);
const io = new SocketIOServer(server, {
    cors: {
        origin: "http://localhost:4200",
        methods: ["GET", "POST"],
        credentials: true
    }
});

app.use(cors({
    credentials:true,
    origin:["http://localhost:4200"]
}));

app.get('/games', (req, res) => {
    const restGames = new RestGames();
    restGames.getGames(req, res);
});

io.on('connection', (socket) => {
    console.log('A user connected');

    socket.emit('messageFromServer', "Congrats, you've connected to our server");

    socket.on('disconnect', () => {
        console.log('User disconnected');
    });
});

const port = 5000;
server.listen(port, () => {
    console.log("Website served on http://localhost:" + port);
})
```

## Socket.IO Service (socket.service.ts)

I've created a SocketService in Angular to manage the Socket.IO connection. The service is designed to establish a connection with the server and provide access to the socket instance.

```
import { Injectable } from '@angular/core';
import io from 'socket.io-client';

@Injectable({
  providedIn: 'root'
})
export class SocketService {
  private socket: any = undefined;

  constructor() {
    if (!this.socket) {
      this.socket = io('http://localhost:5000/');
    }
  }

  public getSocket() {
    return this.socket;
  }
}
```

## Test Component (test.component.ts)

The TestComponent is responsible for displaying messages received from the server. It initializes the socket connection in ngOnInit and listens for messages from the server.

```
import { Component, OnInit } from '@angular/core';
import { SocketService } from "../../services/socket-io.service";

@Component({
  selector: 'app-test',
  templateUrl: './test.component.html'
})
export class TestComponent implements OnInit {
  socket: any;
  messages: string[] = [];

  constructor(private socketService: SocketService) {}

  ngOnInit() {
    this.socket = this.socketService.getSocket();

    console.log('Socket initialized:', this.socket);

    this.socket.on('messageFromServer', (data: any) => {
      console.log('Received message:', data);
      this.messages.push(data);
    });
  }
}
```

## Test Component HTML (test.component.html)

The HTML template for the TestComponent iterates over the messages array to display each received message.

```
<div>
  <ul>
    <li *ngFor="let m of messages">{{ m }}</li>
  </ul>
</div>
```

## Routing Module (app-routing.module.ts)

The routing module defines the application's routes, including the route to the TestComponent.

```
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from "./components/pages/home/home.component";
import { RoulettePageComponent } from "./components/pages/roulette-page/roulette-page.component";
import { TestComponent } from "./components/pages/test.component";

const routes: Routes = [
  { path: '', component: HomeComponent },
  { path: 'game/:id', component: RoulettePageComponent },
  { path: 'test', component: TestComponent }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }
```


Despite following these configurations, the TestComponent fails to load when navigating to the corresponding route, but messages from the server are received, I can see them when I log them. I would appreciate any insights or suggestions on resolving this issue.