ng2-file-upload icon indicating copy to clipboard operation
ng2-file-upload copied to clipboard

FileItem progress property not updating.

Open bryansoto opened this issue 9 years ago • 14 comments

I think PR#30 was reverted. With IE11, Firefox and Chrome (all latest), FileItem progress in console jumps from 0 to 100 with no intermediate values displayed.

bryansoto avatar Oct 12 '16 22:10 bryansoto

Same here.

ghost avatar Oct 31 '16 18:10 ghost

same

rightisleft avatar Nov 15 '16 18:11 rightisleft

I find that if I click the window/view during upload, it suddenly fires the event and shows progress.

ghost avatar Nov 16 '16 07:11 ghost

I'm experiencing the same problem, did one of you found a workaround for this?

deeweey avatar Nov 19 '16 14:11 deeweey

I haven't tried, to be honest. It's a low priority for us in comparison to the rest of the work we have going on. I did see that it's still happening with the latest 1.1.4-2 release though.

bryansoto avatar Nov 21 '16 16:11 bryansoto

I guess the problem is somehow related to the angular change detection. When you activate the change detection manually, the progress(bar) works again.

I just tested it with one item and the progress of this one item:

Inject ChangeDetectorRef to start the change detection manually:

constructor(private changeDetector: ChangeDetectorRef)

Add a handler to the item which is uploaded and call the change detector when the progress changes.

 public uploader: FileUploader = new FileUploader({ url: this.URL });

startUpload() {
    //checks for no selected file ...
    this.uploader.queue[0].onProgress = (progress: any) => {
      this.changeDetector.detectChanges();

    }
    //start Upload ...

I hope this helps ;)

Akkusativobjekt avatar Nov 24 '16 08:11 Akkusativobjekt

Using the .onProgress callback as described by @Akkusativobjekt did not work for me. I could print the progress but not call the change detector. I solved it by forcing angular to detect changes in an interval during the upload:

this.uploader.onCompleteItem = () => {
       clearInterval(this._interval);
     };
startUpload() = () => {
     this.refreshView();
     upload();
}
refreshView() {
    this._interval = setInterval(() => {
      this._changeDetector.detectChanges();
    }, 10);
  }

tobiaseisenschenk avatar Dec 18 '16 20:12 tobiaseisenschenk

@valorkin, I'm also having this issue. While the work around may work, I think it would be best to fix this internally in the library.

The top post shows a PR which is said to be reverted which caused this issue again. Was there a reason it was reverted the first time, or would the correct fix for this to re-instate the fix in #30.

I would be happy to fix this and put out a PR, just looking for a little history before I start down the wrong path.

deeg avatar Jan 16 '17 20:01 deeg

This is a problem because xhr.upload.onprogressand the like inside the FileUploader class are not running inside Angular's Zone and therefore change detection does not know about it.

A quick work around is to inject NgZone and run your onProgress update function inside there so something like this @Akkusativobjekt

constructor(private zone: NgZone) {...}

startUpload() {
    this.uploader.queue[0].onProgress = (progress: any) => {
        this.zone.run(() => {
           //update progress here
           this.progress = progress;
        });
    }
}

@valorkin I'm thinking the FileUploader should just be turned into a service instead of just a class so we don't have to manually run everything in the ngZone.

mkennedy3000 avatar Feb 01 '17 21:02 mkennedy3000

I came up with an equivalent solution but I thought more coupled to the uploader API. Actually, the uploader comes with a set of listeners :

https://github.com/valor-software/ng2-file-upload/blob/development/src/file-upload/file-uploader.class.ts

So, in my case, I just overwrote it, forcing angular to detect changes (this is a typescript example):

this.uploader.onProgressItem = (file: FileItem, progress: any) => {
      this.changeDetector.detectChanges();
      return { file, progress };
    };

Not that it does cover all the states changes of the uploader, in particular, you will have to do the same kind of trick with the onCompleteItem for example to know the upload status.

alexduros avatar Apr 10 '17 15:04 alexduros

I have a similar issue, but mine does not seem to be changeDetection-related. It works fine in Chrome and IE, but in Edge onProgressItem doesn't fire at all until it's at 100%

Markus-ipse avatar Apr 28 '17 12:04 Markus-ipse

Inject ChangeDetectorRef to start the change detection manually:

constructor(private changeDetector: ChangeDetectorRef)

this.uploader.onProgressItem = (progress: any) => this.detector.detectChanges();

It Work like a charm.

sonnguy avatar Jun 15 '17 03:06 sonnguy

There is a better solution:

    (this.uploader as any)._render = () => this.changeDetector.markForCheck();

_render method is called each time when dependent component should be updated it is protected, so properly is to extend base class, but this hack works too

mentatxx avatar Sep 06 '19 18:09 mentatxx

ChangeDetectorRef

Hi, sorry to bring back a thread that has been sleeping for too long, but now I'm struggling with the same and cannot find the full solution, can you elaborate a little more? I haven't bee able to get this working, progress just keeps saying 0 or 100? I think I'm missing just a small piece

camicase82 avatar May 16 '20 15:05 camicase82