title: Using RxJs and Angular 2 in order to deal with server-sent events
body: <p>I am trying to display server-sent events emitted values in an angular 2 /RxJs app.</p>
  
  <p>The backend regularly sends individual strings to the client through server-sent events.</p>
  
  <p>I am not sure how to deal with the retrieved values on the angular 2/RxJs side.</p>
  
  <p>Here is my client (a ng component):</p>
  
  <pre><code>import {Component, OnInit} from 'angular2/core';
  import {Http, Response} from 'angular2/http';
  import 'rxjs/Rx';
  import {Observable}     from 'rxjs/Observable';
  
  @Component({
      selector: 'my-app',
      template: `&lt;h1&gt;My second Angular 2 App&lt;/h1&gt;
      &lt;ul&gt;
          &lt;li *ngFor="#s of someStrings | async"&gt;
             a string: {{ s }}
          &lt;/li&gt;
      &lt;/ul&gt;
      `
  })
  export class AppComponent implements OnInit {
  
      constructor(private http:Http) {
      }
  
      errorMessage:string;
      someStrings:string[];
  
      ngOnInit() {
          this.getSomeStrings()
              .subscribe(
                  aString =&gt; this.someStrings.push(aString),
                  error =&gt; this.errorMessage = &lt;any&gt;error);
      }
  
      private getSomeStrings():Observable&lt;string&gt; {
          return this.http.get('interval-sse-observable')
              .map(this.extractData)
              .catch(this.handleError);
      }
  
      private extractData(res:Response) {
          if (res.status &lt; 200 || res.status &gt;= 300) {
              throw new Error('Bad response status: ' + res.status);
          }
          let body = res.json();
          return body || {};
      }
  
      private handleError(error:any) {
          // In a real world app, we might send the error to remote logging infrastructure
          let errMsg = error.message || 'Server error';
          console.error(errMsg); // log to console instead
          return Observable.throw(errMsg);
      }
  }
  </code></pre>
  
  <p>The backend method is as follows (and uses RxJava):</p>
  
  <pre><code>   @ResponseStatus(HttpStatus.OK)
     @RequestMapping(method = RequestMethod.GET, path = "interval-sse-observable")
      public SseEmitter tickSseObservable() {
          return RxResponse.sse(
                  Observable.interval(5, TimeUnit.SECONDS, Schedulers.io())
                          .map(tick -&gt; randomUUID().toString())
          );
      }
  </code></pre>
  
  <p>I just noticed that the app hangs on the request and that nothing is displayed on the page.</p>
  
  <p>I suspect there is an issue with my use of the map method i.e. <code>.map(this.extractData)</code>.</p>
  
  <p>I would just like to add the incoming strings to the array and display that array in the template which would update as the strings come in.</p>
  
  <p>Can anyone please help?</p>
  
  <p><strong>edit</strong>: Here is a working solution (thanks to Thierry's answer below):</p>
  
  <pre><code>import {Component, OnInit} from 'angular2/core';
  import 'rxjs/Rx';
  
  @Component({
      selector: 'my-app',
      template: `&lt;h1&gt;My second Angular 2 App&lt;/h1&gt;
      &lt;ul&gt;
          &lt;li *ngFor="#s of someStrings"&gt;
             a string: {{ s }}
          &lt;/li&gt;
      &lt;/ul&gt;
      `
  })
  export class AppComponent implements OnInit {
  
      someStrings:string[] = [];
  
      ngOnInit() {
          let source = new EventSource('/interval-sse-observable');
          source.addEventListener('message', aString =&gt; this.someStrings.push(aString.data), false);
      }
  }
  </code></pre>