Angular 12 Change Detections for signalR updates

183 Views Asked by At

We are struggling to refresh the data on screen instantly from a SignalR call within angular. The view updates, but after around 10 seconds, so guessing this has to do with the changedetection? Is there anyway to make this instant?

we have a signalr service which returns an observable :-

export class HotelSignalrService extends SignalrService {
constructor() {
    super();
    this.urlExtention = 'hub';
    if (!this.hubConnected)
        this.startConnection();
}

public getHotelDetails(next) {
    this.hubConnection.off('SendHotelDetails');
    this.hubConnection.on('SendHotelDetails', (message) => {
        next(message);
    });
}

We have an additional SignalR Class which subscribes to these :-

public startHotelConnection(hotelId: number, hotelData: HotelData) {
    this.signalRService.connectToGroup(hotelId.toString());
    this.hotelData= hotelData;

    this.signalRService.getHotelDetails((message: any) => this.updateHotelDetails(message));
}

updateHotelDetails simply updates the hoteldata that is passed in initially with the message from signalR

We have tried passing in a callback function to force a changedetection, but changedetection was null when it was executed (assuming it was disposed of). tried adding change detection into the signalR class, but this wasn't allowed as change detection isnt available.

tried | async to the binding, but this also failed as the hoteldetails is an interface.

Any help or advice would be greatly appreciated.

1

There are 1 best solutions below

0
Meddah Abdallah On

My best guesss on why your method is not working is the way you are updating this.hotelData. Are you making sure the refrence changes ? or are you doing something like this.hotelData[Address] = hotelDetails.newAddress, which will not trigger change detection as the object refrence of hotelData did not change.

However I have a solution using observables that I can suggest and you can use async pipe to make sure your change detection is triggered:

export class HotelSignalrService extends SignalrService {
constructor() {
    super();
    this.urlExtention = 'hub';
    if (!this.hubConnected)
        this.startConnection();
}

public getHotelDetails$() {
    return new Observable((observer) => {
        this.hubConnection.off('SendHotelDetails');
        this.hubConnection.on('SendHotelDetails', (message) => {
           observer.next(message);
        });
    });
}

And in the component

public startHotelConnection(hotelId: number, hotelData: HotelData) {
    this.signalRService.connectToGroup(hotelId.toString());
    this.hotelData$ = of(hotelData);

    this.hotelDetails$ = this.signalRService.getHotelDetails$();
}

Notice that I have put hotelData and hotelDetails in different variables, if you want to combine them into one variable I suggest you use combineLatest along with a map to format your data correctly