I am trying to create a web-app for a game that involves starting and joining rooms. I am using Angular and Socket.io for the project. I have components named Startpage and Lobby. Startpage contains text boxes for player name and Room ID. It also has buttons for "Start Game" and "Join Game". Clicking on the "Start Game" button triggers the startThisGame() function.
//startpage.component.ts
import { Component, OnInit, Output, NgZone } from '@angular/core';
import { Router } from '@angular/router';
import { SocketioService } from '../socketio.service';
@Component({
selector: 'app-startpage',
templateUrl: './startpage.component.html',
styleUrls: ['./startpage.component.css']
})
export class StartpageComponent implements OnInit {
constructor( private router: Router, public zone: NgZone, private socketService: SocketioService ) {}
ngOnInit() {
this.socketService.setupSocketConnection();
}
testRoomId = 'xxxx'
startThisGame() {
var playerName = (document.getElementById("nameInput") as HTMLInputElement).value;
if (playerName) {
this.testRoomId = this.socketService.startGame(playerName);
alert("In component: " + this.testRoomId)
this.zone.run(() => {this.router.navigate(['/lobby']); });
}
else{
alert("Enter a player name!")
}
}
}
The code inside socketService goes as follows.
import { Injectable } from '@angular/core';
import * as io from 'socket.io-client';
import { environment } from 'src/environments/environment';
@Injectable({
providedIn: 'root'
})
export class SocketioService {
socket;
public roomId: string;
public playerName: string;
constructor() {}
setupSocketConnection() {
this.socket = io(environment.SOCKET_ENDPOINT)
alert("Connection set-up")
}
startGame(inputPlayerName) {
this.socket.emit('startGame', {name: inputPlayerName})
this.playerName = inputPlayerName
this.socket.on('recieveRoomId', (data: any) => {
this.roomId = data.code
alert("In service startGame: " + this.roomId)
})
return this.roomId
}
getRoomId() {
alert("In service getRoomId: " + this.roomId)
return this.roomId;
}
}
The server code creates a unique room ID and passes it to the roomId variable in socketService. My first question starts here. If you notice, I have left a trail of alert messages along the way. I would expect the order of alert messages to be alert("In service startGame: " + this.roomId) and then alert("In component: " + this.testRoomId). However, I get the alert messages in the opposite order and the roomId's are undefined even though the server generates and emits a unique roomId. I do not seem to understand why this is happening.
Secondly, you can see that the startThisGame() function causes socketService to store the generated roomId and playerName inside the class and then reroutes the app to the lobby component. The lobby code goes as follows.
import { Component, OnInit, OnChanges, AfterContentInit, SimpleChanges, Input } from '@angular/core';
import { SocketioService } from '../socketio.service';
@Component({
selector: 'app-lobby',
templateUrl: './lobby.component.html',
styleUrls: ['./lobby.component.css']
})
export class LobbyComponent implements OnInit, AfterContentInit {
constructor(private socketService: SocketioService) { }
@Input() roomId: string;
ngOnInit(): void {
// alert("On init fetched")
this.socketService.setupSocketConnection()
this.roomId = this.socketService.getRoomId()
if (this.roomId) {
alert("Value obtained in init: " + this.roomId)
}
else {
alert("No value obtained inside init")
}
document.getElementById("generated_code").innerHTML = this.roomId
}
}
Here, OnInit, the socketService.getRoomId() function returns an undefined value. If I press back, go to the startpage again, enter a playerName and start a new game again, the previously generated roomId is being rendered. What am I missing here? How do I load the roomId and display the same when I am rerouted to the lobby?