Juicy Juicy - 5 months ago 32
TypeScript Question

Getting the server response after xhr.send() in an Observable

I implemented a method to POST a file in my Angular 2 app. It is based on the solution I found here.

Because Angular 2 doesn't support file uploads by itself, the solution has to leverage

. This is what the working solution looks like:

The component method:

onSubmit(): void {
this.inputModuleService.postFile(this.files).subscribe(() => {

The service method:

postFile (files: File[]): Observable<string> {
var url = this.uploadURL;

return Observable.create(observer => {
var formData: FormData = new FormData()
var xhr: XMLHttpRequest = new XMLHttpRequest();

formData.append("upload", files[i], files[i].name);

xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
} else {

xhr.open('POST', url, true);

My issue is that I don't understand how to get the response back to the
method after the call to
. Angular2 and the concept of observables and promises are all new to me.

How can I get the server's response from this observable?


The server response is provided to the success and error callbacks of subscribe():

onSubmit(): void {
      response => {
          //response is the server's response, parsed into a javascript object
          console.log('server responded: ', response);
      error => {
          //server response emitted when xhr.status !== 200

This line:

formData.append("upload", files[i], files[i].name);

Will throw errors because i is undefined. The code you copied from had that line within a loop and i was the current index. That's not the case in your code.

Your function declaration:

postFile (files: File[]): Observable<string>

Should be changed to

postFile (files: File[]): Observable<any>

Because the Observable returned by postFile emits objects, not strings.

If you mean to upload just one file, you should also change files: File[] to file: File and append the file with:

formData.append("upload", file, file.name);