Rxjs subscribes only once, in 1 component, not the same time diff components in angular 14.
Requirements
I am building a notification service, when any customer, submits any case, it's assigned to a support team, and I want to notify customers and the support team at the same time, or 1-2 sec duration, I am using the WebSockets here.
Code - Notification.service.ts
:
import { Injectable } from '@angular/core';
import { Subject, Observable } from "rxjs";
import { Notification, NotificationType } from "../models/notification.model";
@Injectable()
export class NotificationService {
private _subject = new Subject<Notification>();
private _idx = 0;
constructor() { }
getObservable(): Observable<Notification> {
return this._subject.asObservable();
}
info(title: string, message: string, timeout = 3000) {
this._subject.next(new Notification(this._idx++, NotificationType.info, title, message, timeout));
}
success(title: string, message: string, timeout = 3000) {
this._subject.next(new Notification(this._idx++, NotificationType.success, title, message, timeout));
}
warning(title: string, message: string, timeout = 3000) {
this._subject.next(new Notification(this._idx++, NotificationType.warning, title, message, timeout));
}
error(title: string, message: string, timeout = 0) {
this._subject.next(new Notification(this._idx++, NotificationType.error, title, message, timeout));
}
}
In the Notification component, I subscribe like this:
notification.ts
import { debounceTime, Subscription } from "rxjs";
private _subscription: Subscription;
constructor(private _notificationSvc: NotificationService) { }
this._subscription = this._notificationSvc.getObservable().pipe(debounceTime(1000)).subscribe((notification) => {
console.log("I am notification called: -", notification);
this._addNotification(notification)
});
Websockets code:
import { Injectable } from '@angular/core';
import { webSocket, WebSocketSubject } from 'rxjs/webSocket';
import { Subject, Observable, BehaviorSubject, pipe, mergeMap } from "rxjs";
import { environment } from '../../environments/environment';
import { SharedservicesService } from './sharedservices.service';
import { NotificationService } from './notification.service';
@Injectable()
export class WebSocketService {
public subject: WebSocketSubject<any>;
currentUser: any;
params:any;
constructor(private shared: SharedservicesService, private notificationService: NotificationService) {
this.getRequestIds();
}
public getRequestIds() {
this.currentUser = JSON.parse(localStorage.getItem('currentUser'));
if(this.currentUser) {
const data = {
key: this.currentUser["cognito:username"],
}
this.shared.getRequestIds(data).subscribe({
next: async(response) => {
const responseData = JSON.parse(JSON.stringify(response));
this.connect(responseData.result);
},
error: (error) => {
console.log(error);
}
})
}
}
public connect(requestId) {
this.currentUser = JSON.parse(localStorage.getItem('currentUser'));
this.params = "?userId="+this.currentUser["cognito:username"]+"&userEmail="+this.currentUser["email"]+"&userName="+this.currentUser["custom:name"]+"&role="+this.currentUser["custom:role"]+"&requestids="+requestId
this.subject = webSocket({
url: environment.websocketUrlClient+""+this.params,
deserializer: ({ data }) => {
return new Promise((res, rej) => {
res(data);
});
},
openObserver: {
next: () => {
console.log('connecion ok');
},
},
closeObserver: {
next: () => {
console.log('disconnect ok');
this.getRequestIds();
},
},
});
this.subject.subscribe();
}
public send(msg) {
console.log('Send Message:', msg);
this.subject.next(msg);
}
public disconnect() {
this.subject.complete();
}
public receiveMessage() {
this.subject.subscribe(
(msg) => {
if(msg.__zone_symbol__value != "") {
const data = JSON.parse(msg.__zone_symbol__value);
console.log('message received: ', data);
// Problem here ----
// Login 2 diff browser, Customer and support team, When send message, to support team, customer getting notification but support team are not, because support team are not in the same browser, I am using WebSocket to send the message
if(data.sendRoomToAssignedBusinessAnalysts) { // when first Business Analyst is added
console.log("Title:", data.title);
console.log("Body:", data.body);
this.notificationService.success(data.title, data.body)
}
}
},
);
}
}
There are no errors.
Problem
I am getting notifications for the customer, not for the support team member. Because the Rxjs subject, subscribes only once, in 1 component, not same time diff components.
Youtube link (explained about the problem): https://www.youtube.com/watch?v=R5dhCUC3x5s
Github repo: https://github.com/codeztech-atique/angular-websockets-testing-api
Stackblitz: https://stackblitz.com/edit/angular-ivy-eiqr8u
Any help would be appreciated. I am new to this. Might be something I am missing here, Let me know, what could be done.
Your problem is very simple, there is no problem with RxJS or the subscription.
The problem is that you have <app-notification></app-notification>
inside customer.component.html
but inside support.component.html
is missing.
Therefore the notification won't be displayed.
to solve your problem you have to add <app-notification></app-notification>
to support.component.html
.
Then you have <app-notification></app-notification>
in both components. This works but a better solution would be to move <app-notification></app-notification>
to app.component.html
, so you have the component only once and it works everywhere, even if you add more pages.