0
votes

I've been digging an issue with Angular 4 and RxJS. Here is my code, the issue is, the http.post request Observable is not emitting anything to the next of the chain, the map(). The POST just get an endless response, it's a stream of Motion JPEG data. Now I have to deal with the data, say each 500KB transferred. My problem is that I cannot do anything with the data if the Observable not emitting anything.

So how to make such angular HTTP feature emit to the next of the chain each chunk of data transferred?

postActionGivenDataBinaryResponse(url:string, data:string) : Observable<any>{
    let headers = new Headers ({
        'Content-Type' : 'application/json;charset=utf-8'
    }) ;
    let options = new RequestOptions({
        headers : headers,
        responseType: ResponseContentType.ArrayBuffer
    }) ;

    //return binary data as is no json
    return this.http.post(url, data, options) //suspecting here is not emitting anything due to unknown configuration issue.
                    .map(this.extractBinaryData)
                    .catch(this.handleError) ;
}

private extractBinaryData(res:Response){
    console.log('Dealing with data in the com service.') ; // this never runs
    return res ;
}

I call the above function like this, the post response is an endless binary data, I need to process it as string array.

this.mySubscription = this.comService.postActionGivenDataBinaryResponse(myurl,mydata)
  .do(()=>{
              console.log('Observable Passed data.') ; //this never runs.
          })
  .bufferCount(128000)
  .map((data)=>{//process the data each 128kb chunk})
  .subscribe();
2
I don't get what the question is about. Where do you call postActionGivenDataBinaryResponse? Where do you expect a value but don't get one? - Günter Zöchbauer
@GünterZöchbauer, I commented my code for the issue. That function is just a POST. I expect the data would be emitted by chunk, but it never emits now, but debug shows the data is transferred no problem. Need to know why. - tomriddle_1234
@tomriddle_1234 where did you see in the documentation that the Angular Http.post method returned an Observable emitting an event for every byte received in the response? Why do you make that assumption? - JB Nizet
@JBNizet, I would like to know how to solve my situation, are you saying I shouldn't use Angular's HTTP module? I just need http emit event each chunk of data recieved. How? - tomriddle_1234
I have no clear idea. But if it's possible, my guess is that you'll have to use a lower-level mechanism, using XMLHttpRequest directly. - JB Nizet

2 Answers

0
votes

I am assuming you are seeing the response sent from the server on the network tab but its got getting out from the map operator. I am just guessing the problem could be in how you have used the function extractBinaryData() inside the map. Instead, could you just not use the function and just do a .map(res => res) or remove that.. I am assuming the "this" reference inside the map is not the object that holds the extractBinaryData() method. Please try this and let us know if it solved the issue.

0
votes

I solved this issue by a trick that MDN provided. It's about how to transfer binary data

So I wrote my own request instead of using Angular's HTTP module.

And utilizing the responseText trick to keep the request never ending.

The request is like,

function load_binary_resource(url) {
  var req = new XMLHttpRequest();
  req.open('GET', url, false);
  //XHR binary charset opt by Marcus Granado 2006 [http://mgran.blogspot.com]
  req.overrideMimeType('text\/plain; charset=x-user-defined');
  req.send(null);
  if (req.status != 200) return '';
  return req.responseText;
}

I just need to wrap this into an observable, then data would keep streaming and never stop unless the request is abort().