I am using Angular 2 rc3.
I have a service which returns an rxjs Observable, inside of which there are some async tasks and then a recursive HTTP request. It is a chunked upload, so there are multiple sequential requests each triggered in the success handler of the previous chunk.
I would like to know how to cancel the internal HTTP request when I dispose the containing Observable.
This is basically what I'm doing (not real code):
// UploadService
upload (file) {
    return Observable.create((observer) => {
        let reader = new FileReader();
        // convert file into chunks
        let chunkedFile = this.chunkFile(file);
        reader.onloadend = (event) => {
            // THIS IS THE REQUEST I WANT TO CANCEL
            this.http.put('url/to/upload/to', chunkedFile.currentChunk)
                .subscribe((res) => {
                    // emit some data using containing observable, e.g. progress info
                    observer.next(res);
                    // trigger upload of next chunk
                    this.uploadFileInChunks(reader, chunkedFile, observer);
                });
        };
        // this triggers the onloadend handler above
        this.uploadFileInChunks(reader, chunkedFile, observer);
    });
}
And then I use it in my component like this:
// ExampleComponent
upload () {
    this.uploader = this.uploadService.upload(file)
        .subscribe((res) => {
            // do some stuff, e.g. display the upload progress
        })
}
ngOnDestroy () {
    // when the component is destroyed, dispose of the observable
    this.uploader.dispose();
}
I can see in the network panel that after destroying the component the upload progress still continues.
How can I cancel it?
If it helps to understand the upload, then I'm using this https://github.com/kinstephen/angular-azure-blob-upload ported to Angular 2
You need to return a function within the observable creation callback. This function will be called when calling the dispose method:
return Observable.create((observer) => {
  (...)
  return () => {
    // code to dispose / cancel things 
  };
});
To cancel the request within the uploadFileInChunks method, you need to save the subscription and call its unsuscribe method.
reader.onloadend = (event) => {
  // THIS IS THE REQUEST I WANT TO CANCEL
  this.subscription = this.http.put('url/to/upload/to', chunkedFile.currentChunk)
         .subscribe((res) => {
           // emit some data using containing observable, e.g. progress info
           observer.next(res);
           // trigger upload of next chunk
           this.uploadFileInChunks(reader, chunkedFile, observer);
         });
};
() => {
  if (this.subscription) {
    this.subscription.unsubscribe();
  }
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With