DEV Community

Nacho Colomina Torregrosa
Nacho Colomina Torregrosa

Posted on

Subscribing to server sent events with Angular

In this article, I will cover how to subscribe to server sent events from an Angular application.

Server sent events allow servers to send data to clients by pushing messages to the them.

Starting from a running angular application and assuming we are using mercure as a backend, let's add all we would need to subscribe to sse topics.

Creating the models

  export interface User {
    name: string;
    id: string;
  }

  export interface Topic {
    getTopic(user: User): string;
  }

  export class PaymentTopic implements Topic{
    getTopic(user: User): string {
      return 'https://topics.domain.com/' + user.id + '/payments';
    }
}
Enter fullscreen mode Exit fullscreen mode

Above we can see three models:

  • Interface user: Holds user data
  • Interface topic: Declares getTopic method
  • Class PaymentTopic : Implements Topic interface (represents a topic to subscribe to).

PaymentTopic returns a topic url with the user id. It would allow us to subscribe users only to their payments.

Creating the service to subscribe to topic

  export interface MessageData {
    status: string;
    message: string;
  }

  export class SseService {

    constructor() { }

    createEventSource(user: User, topic: Topic): Observable<MessageData> {
      const topicUri = topic.getTopic(user);
      const eventSource = new EventSource(environment.sse_url + '?topic=' + topicUri);

      return new Observable(observer => {
          eventSource.onmessage = event => {
            const messageData: MessageData = JSON.parse(event.data);
            observer.next(messageData);
        };
      });
   }
}
Enter fullscreen mode Exit fullscreen mode

Method createEventSource receives a user and a topic (any class which implements Topic interface) and uses EventSource to subscribe. It will return an Observable which keeps listening to onmessage EventSource event and notifies received message to the element subscribed to it.

Creating the component and using the service

export class SseComponent implements OnInit {

  constructor(private sseService: SseService) { }

  ngOnInit(): void {
    const user: User = {
      id: '65PRG6RD0C87KAQV8RS8H5HHBR',
      name: 'Jose'
    };

    const topic = new PaymentTopic();
    this.sseService.createEventSource(user, topic).subscribe(
      (e: MessageData) => {
        console.log('Message received: ' + e.message);
      }
    );


  }

}
Enter fullscreen mode Exit fullscreen mode

As we can see, SseComponent injects SseService and uses it to subscribe to payment topic. When server pushes a message to the topic it will be logged on the browser console.

Top comments (1)

Collapse
 
artydev profile image
artydev

Great thank you :-)