0

I'm creating a custom file up-loader for my project. I want to add "cancel file upload feature" also. Assume that I've already dragged and dropped some 4 or 5 file into the component. this files are stored in file variable. When I click on "Upload" button from the UI following method will be called:

uploadFiles() {
    const formData = new FormData();
    formData.append('excel', this.file);
    const headers = new HttpHeaders({
      'x-request-id': 'file_upload_' + new Date().getTime(),
    });
    this.http
      .post('http://localhost:8090/service/fileprocess/upload', formData, {
        headers: headers,
        responseType: 'json',
      })
      .pipe(catchError((err) => this.handleError(err)))
      .subscribe((res: any) => {
         // show success message to the user
      });
}

Let's say I pressed the upload button but there is one file which is taking longer than expected. Then the user should be able to cancel that particular upload by clicking on its respective ban icon. This is my template:

<div class="row mt-1" *ngFor="let item of files; let indexOfelement=index;">
  <div class="col-lg-1">
    <p-progressSpinner *ngIf="fileUploading"></p-progressSpinner>
  </div>
  <div class="col-lg-3">
    {{ item.relativePath }}
  </div>
  <div class="col-lg-6">
    <p-progressBar *ngIf="fileFound" [value]="variable"></p-progressBar>
  </div>
  <div class="col-lg-2 text-end">
    <i class="fa fa-ban" *ngIf="fileUploading" (click)="stopThisUpload(indexOfelement)"></i>
  </div>
</div>

The UI looks like this: enter image description here

Can someone please guide me on this.

Tanzeel
  • 4,174
  • 13
  • 57
  • 110
  • check this other answers: https://stackoverflow.com/questions/36490926/how-to-cancel-a-httprequest-in-angular-2 – dmance Nov 04 '22 at 07:27

2 Answers2

2

If your request included all files to upload in one request, it is not possible to just remove one single file from the request "on the fly".

But let's assume that your files will be uploaded sequentially (which is not clear from your question), you can just unsubscribe from your request, which will result in angular cancelling the ongoing request:

sub = this.http
  .post('http://localhost:8090/service/fileprocess/upload', formData, {
    headers: headers,
    responseType: 'json',
  })
  .pipe(catchError((err) => this.handleError(err)))
  .subscribe((res: any) => {
    // show success message to the user
  });

....

// in click handler
sub.unsubscribe();

Of course you can also define a Subject, which will have the same effect (unsubscribing if a value is emitted):

unsubscribCurrentFile = new Subject<void>();
...
sub = this.http
  .post('http://localhost:8090/service/fileprocess/upload', formData, {
    headers: headers,
    responseType: 'json',
  })
  .pipe(takeUntil(this.unsubscribeCurrentFile), catchError((err) => this.handleError(err)))
  .subscribe((res: any) => {
    // show success message to the user
  });

....

// in click handler
this.unsubscribCurrentFile.next();
Fabian Strathaus
  • 3,192
  • 1
  • 4
  • 26
  • I'm trying out your solution. I'll be back with the results. thanks. – Tanzeel Nov 04 '22 at 07:38
  • The subject name should end with '$', so the name should be `unsubscribe$`, or `unsubscribeCurrentFile$`. And also, don't forget to `complete()` the subject in `ngOnDestroy()`. – Aid Hadzic Nov 04 '22 at 07:55
  • Well, yes and no. I think this is debatable :D Coding conventions say, that observables should have a trailing dollar sign. Indeed, a subject is also an observable, but also has some additional properties. But of course the interpretation of this convention is up to the reader. Thanks for your input nevertheless! – Fabian Strathaus Nov 04 '22 at 07:59
0

it's a good case for using the AbortController from Fetch api.

For example:

const controller = new AbortController();
const signal = controller.signal;

function abortRequest() {
  controller.abort();
  console.log("aborted");
}

function fetchVideo() {
  fetch(url, { signal })
    .then((response) => {
      console.log("Download complete", response);
    }).catch((err) => console.error(err.message));
}

references:

https://developer.mozilla.org/en-US/docs/Web/API/AbortController/abort

Fábio BC Souza
  • 1,170
  • 19
  • 22