2

In my Angular 8 app based on ASP.NET MVC, there is a Dashboard component where I display some kind of statistical data (e.g. sum, average numbers) and I update these data with the help of SignalR after each Create-Update-Delete event by broadcasting new data to all of the clients. On the other hand, I want to build a generic way that should be used throughout the entire app and I think it seems to be good idea to use EventEmitter, BehaviorSubject, Subject, ReplaySubject, etc. in order to pass newly retrieved statistical data to the clients. But there are some kind of differences between these components as indicated on Subject vs BehaviorSubject vs ReplaySubject in Angular, I would like to be clarified on which one is most suitable for the given example? And why?

Note that I need to pass multiple data to the clients across different components that have no parent-child relations (generally between sibling components).

Here is my code when I use EventEmitter. But I think BehaviorSubject might be better for my situation:

service.ts:

@Injectable()  
export class SignalRService {  
  messageReceived = new EventEmitter<ChatMessage>();  
  connectionEstablished = new EventEmitter<Boolean>();

  constructor() {  
    this.registerOnServerEvents();  
    this.startConnection();  
  }

  private startConnection(): void {  
    this._hubConnection  
      .start()  
      .then(() => {  
        this.connectionEstablished.emit(true);  
      })
  }  

  private registerOnServerEvents(): void {  
    this._hubConnection.on('ReceiveMessage', (data: any) => {  
      this.messageReceived.emit(data);  
    });  
  }  
}  


component.ts:

export class ClockComponent { 

  constructor(private _signalRService: SignalRService, private _ngZone: NgZone) {  
      this.subscribeToEvents();
  }  

  private subscribeToEvents(): void {  
      this._signalRService.connectionEstablished.subscribe(() => {  
          this.canSendMessage = true;  
      });  

      this._signalRService.messageReceived.subscribe((message: GetClockTime) => { 
          this._ngZone.run(() => {  
              this.allMessages = message;  
          });  
      });  
  }  
}  
Rob
  • 14,746
  • 28
  • 47
  • 65
Jack
  • 1
  • 21
  • 118
  • 236

1 Answers1

1

In your example, the usage of EventEmitter is logically fine but you must avoid using EventEmitter for the broadcast. EventEmitter should be used for @Output properties. Although as per current angular code, EventEmitter is derived from Subject but there could be a chance that implementation of EventEmitter changed as stated here.

You should use either Subject/BehaviorSubject as per your need.

Using Subject, subscriber will get new values which are emitted after the subscription.

Using BehaviorSubject subscriber will get the last emitted value as soon as the subscriber subscribes to the observable and all the future emitted values.

user2216584
  • 5,387
  • 3
  • 22
  • 29
  • Perfect!.. Now I am sure that I need to use Subject or BehaviorSubject according to my situation, many thanks... – Jack Jul 17 '19 at 10:50
  • According to my situation (updating data on Dashboard after Create or Delete), which one is most suitable? The critical point is that when first opening Dashboard page, the data can be retrieved from the database and at this first load, there is no need to use SignalR or no nedd to broadcast. This means no need to emit the value to the clients. In this scenario, I think I get new values after subscription and for this reason I should use Subject. Is that true? If I can use BehaviorSubject in this scenario I think it is better to use it as it has some advantages. Any help pls? – Jack Jul 17 '19 at 10:50
  • @Jack I vote for `BehaviorSubject` as it gives some initial state on subscription. I apply rxjs operators like `filter` if I do not want to process initial value. – user2216584 Jul 17 '19 at 11:57