shiv
shiv

Reputation: 393

Extracting Image Data from response: Angular 2

The response has the image data but I am unable to extract it from the response.

CLIENT CODE-

download() {
    this._http.get('http://localhost:9000/download/' + this._fileid)
    .subscribe(
    data => {
        this.image = data;
    },
    err => console.log('Error is..:' + err)
    );
}

SERVER CODE-

app.get('/download/:fileid', function(req, res) {
    var id = req.params.fileid;
    res.set('Content-Type', 'image/jpeg');
    gfs.createReadStream({_id: id}).pipe(res);
});

[EDIT]- I have adapted my code to use CustomXhr but however I get an empty blob with no data.

CUSTOM XHR CODE-

@Injectable()
export class CustomBrowserXhr extends BrowserXhr {
  build(): any {
    let xhr = super.build();
    xhr.responseType = "blob";
    return <any>(xhr);
  }
}

BOOTSTRAP CODE-

export function main(initialHmrState?: any): Promise<any> {

  return bootstrap(App, [
    ...ENV_PROVIDERS,
    ...PROVIDERS,
    ...DIRECTIVES,
    ...PIPES,
    ...APP_PROVIDERS,
     provide(BrowserXhr, { useClass: CustomBrowserXhr })
  ])
  .catch(err => console.error(err));
}

HTTP REQUEST-

download() {
  this._http.get('http://localhost:9000/download/' + this._fileid)
    .toPromise()
    .then(res => {
      if (res.headers.get("Content-Type").startsWith("image/")) {
          var blob = new Blob([new Uint8Array(res._body)], {
              type: res.headers.get("Content-Type")
          });
          var urlCreator = window.URL;
          var url = urlCreator.createObjectURL(blob);
          console.log(url);
          this.image = url;
      }
    })
}

Upvotes: 5

Views: 16293

Answers (2)

Thierry Templier
Thierry Templier

Reputation: 202326

In fact, it's not so simple at the moment since you can't set the responseType property on the request with Angular2 (there is a pending PR for this).

As a workaround, you need to extend the BrowserXhr class of Angular2 as described below to set the responseType to blob on the underlying xhr object:

import {Injectable} from 'angular2/core';
import {BrowserXhr} from 'angular2/http';

@Injectable()
export class CustomBrowserXhr extends BrowserXhr {
  constructor() {}
  build(): any {
    let xhr = super.build();
    xhr.responseType = "blob";
    return <any>(xhr);
  }
}

Then you need to wrap the response payload into a Blog object:

downloadFile() {
  this.http.get(
  this.http.get(
       'https://mapapi.apispark.net/v1/images/sparky_right.png')
    .subscribe(
      (response) => {
        var mediaType = 'image/png';
        var blob = new Blob([response._body], {type: mediaType});
        (...)
      });
}

See this plunkr: See this plunkr: http://plnkr.co/edit/2ZodNBmv8OVj3LZSrozG?p=preview.

See these question for more details:

Upvotes: 0

Abdulrahman Alsoghayer
Abdulrahman Alsoghayer

Reputation: 16540

What you are looking for is arrayBuffer(). Your code will be:

download() {
    this._http.get('http://localhost:9000/download/' + this._fileid)
    .subscribe(
    data => {
        this.image = data.arrayBuffer();
    },
    err => console.log('Error is..:' + err)
    );
}

But, unfortunately, arrayBuffer() is not yet implemented as of beta.13.

You could instead use XMLHttpRequest, Here is a plunker

getImage(url:string){ 
 return Observable.create(observer=>{
  let req = new XMLHttpRequest();
  req.open('get',url);
  req.responseType = "arraybuffer";
  req.onreadystatechange = function() {
    if (req.readyState == 4 && req.status == 200) {
      observer.next(req.response);
      observer.complete();
    }
  };
  req.send();
 });
}

Upvotes: 12

Related Questions