4

I have a strange problem with signalr and angular. We recently upgraded signalr to use the @microsoft/signalr package instead of the @aspnet/signalr one and we noticed that the callback called by signalr are no longer run in the angular zone.

The significant code bits:

 // connection is of type HubConnection
public async onUpdateJobInfo(callback: (jobInfo: JobInfo) => void): Promise<void> {
        return this.connection.on('someInvokedMethod', callback);
    }

 // Register the callback
this.jobHub.onUpdateJobInfo((jobInfo: JobInfo) => this.updateJobInfo(jobInfo));

// Process the callback 
private updateJobInfo(jobInfo: JobInfo): void {
        console.log('update jobservice in zone: ', NgZone.isInAngularZone());
        
    }

The log (update jobservice in zone: false) indicates that we are not running the callback in the angular zone, hence change detection does not work as expected. When using a similar setup with the old signalr the code runs in the angular zone as expected. Is this a known recent change? How to best cope with this? Encapsulate everything with a zone.run() statement?

Thanks for the help!

1 Answers1

0

We also started having issues with Angular not rendering changes (so we must call detectChanges method). It started after upgrading signalr package but not from @aspnet/signalr to @microsoft/signalr.

We already had @microsoft/signalr .NET 5.0 (microsoft/signalr@5.0.14) which was fine, but upgrading to @microsoft/signalr .NET 6.0 (e.g. microsoft/signalr@6.0.2) started the Angular screen updates issues.

We had to downgrade back to 5.0.14.

Yunnosch
  • 26,130
  • 9
  • 42
  • 54
Itzik
  • 11
  • 2
  • Did you find a solution to this issue using @microsoft/signalr .NET 6.0? Thanks. @sander-dechamps – Itzik May 02 '22 at 15:39
  • We 'solved' it by creating a base class for our hubs which wrap the 'connection.on' method and force the callback into the zone ("@microsoft/signalr": "^6.0.0-preview.3.21201.13"): `protected on(method: string, callback: (...args: any[]) => void): void { return this.connection.on(method, this.callbackHandler.bind({zone: this.zone, callback})); } private callbackHandler(...args: any[]): void { if(this.zone) { this.zone.run(() => { (this as any).callback(...args); }); } else { (this as any).callback(...args); } }` – Sander Dechamps May 03 '22 at 06:37