Search code examples
angularangular2-observables

I don't seem to be getting blob data in my message from my websocket host to my Angular 2 Observable


I'm trying to convert some html/javascript to Angular 2 but I don't seem to be getting blob data in my message from my websocket host to my Angular 2 Observable.

Messages from my websocket host seem to be sending text messages just fine but blob messages show as empty objects.

Here's some of my code:

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Rx';
import { Component } from '@angular/core';

@Injectable()
export class WebSocketService {
  private websocket: any;
  public sendMessage(text:string){
    this.websocket.send(text);
  }
  public GetInstanceStatus(): Observable<any>{
    this.websocket = new WebSocket("ws://localhost:8080/something");
    return Observable.fromEvent(this.websocket,'message').map(res=>res);
  }
  sendText(json: Object) {
    this.websocket.send(json);
  }
  sendBinary(bytes: any) {
    this.websocket.send(bytes);
  }
}

@Component({
  selector: 'my-app',
  templateUrl: 'app/app.component.html'
})
export class AppComponent {
  constructor(
    private wss: WebSocketService
  ){
    this.wss.GetInstanceStatus().subscribe((result) => {
      console.log("received: " + result);
      var foo = result.data;
      for(var name in foo) {
        console.log( name + "::" + foo[name] )
      }
    });
  }
}

Solution

  • Blob data would need to be parsed differently. Angular's Http service returns a ResponseData object that has a .blob() method on it, but unfortunately no support for WebSockets yet :/

    You would have to parse it the old-fashioned way, by using the FileReader:

    public GetInstanceStatus(): Observable<any>{
    var reader = new FileReader();
    this.websocket = new WebSocket("ws://localhost:8080/something");
    
    return Observable.fromEvent(this.websocket,'message')
      .map((res) => {
       // logic here for determining if res is a blob based on headers
       // here is what you'd do for a blob though:
       reader.readAsArrayBuffer(res.body)
      });
    }
    

    The implementation of this is going to vary based on your payload. The readAsArrayBuffer method will parse the data as an array; this might not be what you need. Check out the MDN docs on FileReader here.

    The main point is that you're going to want to do some mapping logic to see whether it should be parsed as a blob or not and return it that way.