diff --git a/src/app/components/application-list/application-list.component.ts b/src/app/components/application-list/application-list.component.ts index 3e7794e..564c20c 100644 --- a/src/app/components/application-list/application-list.component.ts +++ b/src/app/components/application-list/application-list.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, inject, signal, computed, effect } from '@angular/core'; +import { Component, OnInit, inject, signal, computed, effect, OnDestroy } from '@angular/core'; import { CandidateDataService } from '../../services/candidate-data.service'; import { Router, RouterLink } from '@angular/router'; import { FormsModule } from '@angular/forms'; @@ -36,7 +36,7 @@ Chart.register(...registerables); templateUrl: './application-list.component.html', styleUrls: ['./application-list.component.scss'] }) -export class ApplicationListComponent implements OnInit { +export class ApplicationListComponent implements OnInit, OnDestroy { dataService = inject(CandidateDataService); socketService = inject(SocketIOService); router = inject(Router); @@ -176,11 +176,13 @@ export class ApplicationListComponent implements OnInit { }); } + get isLoading() { return this.dataService.isCandidatesListLoading(); } ngOnInit(): void { + this.socketService.connect(); this.dataService.loadCandidateList().subscribe(data => { this.dataService.cachedApplicationList.set(data); this.availableCities.set(this.getUniqueCities(data)); @@ -204,9 +206,12 @@ export class ApplicationListComponent implements OnInit { ); this.availableCities.set(this.getUniqueCities(this.dataService.cachedApplicationList())); }); + } - + ngOnDestroy(): void { + this.socketService.disconnect(); + } getUniqueCities(data: any[]): City[] { const seen: string[] = []; diff --git a/src/app/components/application/application.component.ts b/src/app/components/application/application.component.ts index 3e9b77a..ff2aa48 100644 --- a/src/app/components/application/application.component.ts +++ b/src/app/components/application/application.component.ts @@ -1,4 +1,4 @@ -import { Component, inject, OnInit, signal, computed } from '@angular/core'; +import { Component, inject, OnInit, signal, computed, OnDestroy } from '@angular/core'; import { CandidateDataService } from '../../services/candidate-data.service'; import { ActivatedRoute, Router, RouterLink, RouterModule } from '@angular/router'; import { MatIconModule } from '@angular/material/icon'; @@ -35,7 +35,7 @@ import { tap } from 'rxjs'; ]), ], }) -export class ApplicationComponent implements OnInit { +export class ApplicationComponent implements OnInit, OnDestroy { dataService = inject(CandidateDataService); socketService = inject(SocketIOService); activatedRoute = inject(ActivatedRoute); @@ -68,6 +68,7 @@ export class ApplicationComponent implements OnInit { ngOnInit(): void { + this.socketService.connect(); if (this.dataService.cachedApplicationList().length > 0) { this.initializeApplication(); return; @@ -84,6 +85,10 @@ export class ApplicationComponent implements OnInit { } + ngOnDestroy(): void { + this.socketService.disconnect(); + } + editApplication() { const app = this.currentApplication(); if (!app) return; diff --git a/src/app/components/registration/registration.component.ts b/src/app/components/registration/registration.component.ts index b69cb7f..5d31861 100644 --- a/src/app/components/registration/registration.component.ts +++ b/src/app/components/registration/registration.component.ts @@ -1,4 +1,4 @@ -import { AfterViewInit, Component, ElementRef, inject, input, OnInit, QueryList, Renderer2, signal, ViewChildren } from '@angular/core'; +import { AfterViewInit, Component, ElementRef, inject, input, OnDestroy, OnInit, QueryList, Renderer2, signal, ViewChildren } from '@angular/core'; import { FormBuilder, Validators, ReactiveFormsModule } from '@angular/forms'; import { CommonModule } from '@angular/common'; import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar'; @@ -35,9 +35,7 @@ const israeliPhoneRegex = /^(?:(?:(\+?972|\(\+?972\)|\+?\(972\))(?:\s|\.|-)?([1- templateUrl: './registration.component.html', styleUrls: ['./registration.component.scss'], }) -export class RegistrationComponent implements OnInit { - - +export class RegistrationComponent implements OnInit, OnDestroy { dataService = inject(CandidateDataService); fb = inject(FormBuilder); router = inject(Router); @@ -64,6 +62,7 @@ export class RegistrationComponent implements OnInit { }); ngOnInit(): void { + this.socketService.connect(); const idParam = this.activatedRoute.snapshot.paramMap.get('id'); const url = this.activatedRoute.snapshot.url.map(s => s.path); @@ -78,6 +77,10 @@ export class RegistrationComponent implements OnInit { } } + ngOnDestroy(): void { + this.socketService.disconnect(); + } + loadCandidate(id: number) { this.dataService.getApplicationDetails(id).subscribe({ next: (candidate: any) => { @@ -151,7 +154,7 @@ export class RegistrationComponent implements OnInit { horizontalPosition: 'center', verticalPosition: 'top', }); - this.socketService.socket.emit('candidateUpdated', updatedCandidate); + this.socketService.socket?.emit('candidateUpdated', updatedCandidate); this.router.navigate(['/application-list']); }, error: err => alert('Error updating application'), @@ -167,7 +170,7 @@ export class RegistrationComponent implements OnInit { this.dataService.cachedApplicationList.update((data) => { return { ...data, newCandidate }; }) - this.socketService.socket.emit('candidateRegistered', newCandidate); + this.socketService.socket?.emit('candidateRegistered', newCandidate); this.applicationId.set(newCandidate.id); this.router.navigate([`/application/${this.applicationId()}`]) }, diff --git a/src/app/services/socket-io.service.ts b/src/app/services/socket-io.service.ts index 4ca7afd..1b31fab 100644 --- a/src/app/services/socket-io.service.ts +++ b/src/app/services/socket-io.service.ts @@ -1,18 +1,23 @@ import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; -import { io } from "socket.io-client"; +import { io, Socket } from "socket.io-client"; import { environment } from '../../environments/environment'; @Injectable({ providedIn: 'root' }) export class SocketIOService { + socket: Socket | null = null; + + connect(){ + if(this.socket) return; + this.socket = io(`${environment.socketUrl}`); + } - socket = io(`${environment.socketUrl}`); onCandidateRegistered(): Observable { return new Observable(observer => { - this.socket.on('candidateRegistered', (data) => { + this.socket?.on('candidateRegistered', (data) => { observer.next(data); }); }); @@ -20,7 +25,7 @@ export class SocketIOService { onCandidateUpdated(): Observable { return new Observable(observer => { - this.socket.on('candidateUpdated', (data) => { + this.socket?.on('candidateUpdated', (data) => { observer.next(data); }); }); @@ -28,7 +33,7 @@ export class SocketIOService { onCandidateDeleted(): Observable { return new Observable(observer => { - this.socket.on('candidateDeleted', (data) => { + this.socket?.on('candidateDeleted', (data) => { observer.next(data); }); }); @@ -36,16 +41,16 @@ export class SocketIOService { onStatsUpdated(): Observable { return new Observable(observer => { - this.socket.on('statsUpdated', (data) => { + this.socket?.on('statsUpdated', (data) => { observer.next(data); }); }); } - // disconnect() { - // this.socket.disconnect(); - // } + disconnect() { + this.socket?.disconnect(); + } } diff --git a/src/app/services/stats.service.ts b/src/app/services/stats.service.ts index bf3451b..a265335 100644 --- a/src/app/services/stats.service.ts +++ b/src/app/services/stats.service.ts @@ -1,13 +1,21 @@ -import { Injectable, signal, effect, inject } from '@angular/core'; +import { Injectable, signal, effect, inject, OnDestroy, OnInit } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { SocketIOService } from './socket-io.service'; import { environment } from '../../environments/environment'; @Injectable({ providedIn: 'root' }) -export class StatsService { +export class StatsService implements OnInit, OnDestroy { + http = inject(HttpClient); socket = inject(SocketIOService); + ngOnInit(): void { + this.socket.connect(); + } + + ngOnDestroy(): void { + this.socket.disconnect(); + } totalVisits = signal(0); totalClicks = signal(0);