PrimeNG File Upload Progress does not update when using custom uploadHandler

Viewed 1889

I am trying to use the PrimeNG File Upload Component

But I am uploading to an API so I am using a custom uploadHandler like so:

<p-fileUpload #fileUpload name="fileUpload" 
              (uploadHandler)="uploadHandler($event)" customUpload="true" fileLimit="5"
              multiple="multiple" accept="image/*" maxFileSize="1000000">
</p-fileUpload>

With a component.ts that invokes the following:

uploadedFiles: any[] = [];
@ViewChild('fileUpload') fileUpload: any;

constructor(private wpService: WordpressService, private cd: ChangeDetectorRef) {}

async uploadHandler(event) {
    console.log(this.fileUpload)
    this.fileUpload.disable = false;
    this.fileUpload.progress = 5;
    this.fileUpload.onProgress.emit({progress: this.fileUpload.progress});
    this.cd.detectChanges();
    this.uploadedFiles = [];

    const perFilePercent = 95 / event.files.length;
    this.fileUpload.disable = true;
    for (const f of event.files) {
        await this.wpService.uploadFile(f).then(response  => {
            const thisFile = f;
            thisFile.id = response.id;
            thisFile.url = response.source_url;
            this.fileUpload.progress += perFilePercent;
            this.fileUpload.onProgress.emit({progress: this.fileUpload.progress});
            this.cd.detectChanges();
            this.uploadedFiles.push(thisFile);
    });
    }

    this.fileUpload.files = [];
    this.cd.detectChanges();
}

The issue is that even though I am trying to force the progress to change manually by doing this.fileUpload.progress += perFilePercent; AND this.fileUpload.onProgress.emit({progress: this.fileUpload.progress});, nothing happens.

The curious bit is that if I then bind a progress bar component to the value of this.fileUpload.progress, it will update. For Example:

<p-progressBar [value]="fileUpload.progress" [showValue]="false"></p-progressBar>

Causes the behaviour to work as expected, while the progress bar inside the the actual file upload component stalls and does not update past the very first invocation.

A video of this behaviour: https://bitz.rocks/ftp/3HJvut0t6p.mp4

I feel like I am doing something wrong in the lines that set the viewchild values or the event emitter but I cannot figure out what is wrong nor what I should be doing.

1 Answers

i know its an old post, but i was having a similar task today and that is how i solved it.

/*before constructor*/

totalPercent = 0;
percentDone: number;
@ViewChild('primeFileUpload') primeFileUpload: FileUpload;
private percentDonePerFile: number;

async fileUpload($event) {
    if ($event && $event.files) {
      this.totalPercent = $event.files.length * 100;
      this.percentDone = 0;
      console.log('uploading..');
      let sub;
      let i = 1;
      for (const file of $event.files) {
        const path = '/my/super/path';
        sub = this.docService.percentSub.subscribe(perc => {
          this.percentDonePerFile = perc;
          this.percentDone = (i - 1) * 100 + this.percentDonePerFile;
          console.log('emitting: ' + (this.percentDone / this.totalPercent * 100));
          this.primeFileUpload.onProgress.emit(this.round(this.percentDone / this.totalPercent * 100));
        });
        const dummyEvent = {srcElement: {files: [file]}};
        await this.docService.uploadFile(dummyEvent, path);
        this.percentDone = i * 100;
        this.primeFileUpload.onProgress.emit(this.round(this.percentDone / this.totalPercent * 100));
        console.log('emitting: ' + (this.percentDone / this.totalPercent * 100));
        sub.unsubscribe();
        i++;
      }
    }
  }

  progressReport($event: any) {
    this.primeFileUpload.progress = $event;
  }

my html file is a simple as:

      <p-fileUpload customUpload="true" #primeFileUpload
                multiple="true" (onProgress)="progressReport($event)"
                accept="image/*" maxFileSize="2000000" (uploadHandler)="fileUpload($event)"></p-fileUpload>

It might help someone out! Have a great day

Related