3

I have this progress bar

<div class="progress progress-striped" ng-class"{active: file.isUploading()}">
    <div class="progress bar" role="progressbar" ng-style="{'width' : (file.sizeUploaded() / file.size * 100) + '%'}"></div>
</div>

After debugging with chrome dev tools, I am sending the good width to ng-style. When I stop the execution (Using F8 in source code), the style update to the good width. If I don't stop the execution, the bar goes slowly to barely 1% then when the upload as reached 100%, the bar goes from 1 to 100%.

I am using ng-flow in order to upload my files in chunks rather then one full file.

Here some images to show the behavior:
First image show it isn't updating the style fast enough (The bar at 0% doesn't show a tiny blue bar) Not updated This is what happens when the file is completely uploaded When finished When I press F8 in developer tools source code (Debugging) the style is updated correctly. Updated when in debug

Here is a link to a working example of an upload with progress bar.

I tried using file.progress() in the ng-style, but it does the same behavior. While out of debugger, the size uploaded change just fine, it's really just the ng-style that doesn't seems to update.

Edit: Testing in Firefox, the bar load slightly faster, up to around 5-10% when the file reach 100%.

Edit 2:

sizeUploaded: function () {
  var size = 0;
  each(this.files, function (file) {
    size += file.sizeUploaded();
  });
  return size;
}

Here the html...

<div flow-init flow-name="flow" class="span5 clearfix">
    <div class="alert" flow-drop>
        Drag And Drop your file(s) here
    </div>

    <span class="btn" flow-btn><i class="icon icon-file"></i> Upload File</span>

    <div ng-repeat="file in flow.files">
        {{file.name}} ({{file.size}} kB)
        <br />
        IS COMPLETE: {{file.isComplete()}}
        <br />
        ERROR: {{file.error}}
        <br />
        SIZE UPLOADED: {{file.sizeUploaded()}} kB
        <br />
        IS UPLOADING: {{file.isUploading()}}
        <br />
        {{file.sizeUploaded()}} kB / {{file.size}} kB | {{file.sizeUploaded() / file.size * 100 | number:0}}%
        <div class="progress active progress-striped" ng-class"{active: file.isUploading()}">
            <div class="progress bar" role="progressbar" ng-style="{'width' : (file.sizeUploaded() / file.size * 100) + '%'}">{{file.sizeUploaded()}} / {{file.size}} kB | {{file.sizeUploaded() / file.size * 100 | number:0}}%</div>
        </div>
        <input type="button" ng-click="file.resume()" value="Start/Resume" />
        <input type="button" ng-click="file.pause()" value="Pause"/>
    </div>


    <table>
        <tr ng-repeat="file in flow.files">
            <td>{{$index+1}} | </td>
            <td>{{file.name}}</td>
        </tr>
    </table>
</div>

Additional note: I am using Angular 1.1.5

snaplemouton
  • 1,459
  • 14
  • 28
  • The fact that it is updating at start and then at end, or during a debug break/pause seems to indicate that you or ng-flow are missing $apply somewhere. Post a fiddle or plunker example and I'm sure someone will be able to assist. Or at the bare minimum post the code of `file.sizeUploaded()` – Beyers Feb 10 '14 at 21:55
  • file.sizeUploaded() came with flow so I doubt the problem come from there. I posted the sizeUploaded and will make a fiddle as soon as I get the time – snaplemouton Feb 11 '14 at 14:19
  • Can't get a jsFiddle or Plunker together because there is too many files included with flow and ng-flow, I updated my question to show the html code. – snaplemouton Feb 11 '14 at 15:22
  • the release build of ng-flow is a total of 1 file: https://github.com/flowjs/ng-flow/releases/download/v2.0.0/build.zip and you dont need flow.js separately as it comes bundled with the release file of ng-flow, as per the readme file of ng-flow: `Download a latest build.zip from https://github.com/flowjs/ng-flow/releases it contains development and minified production files, they are also concatenated with core flow.js library.` So go ahead and setup a fiddle. If you are not prepared to do the ground work how on earth do you expect someone else to do it for you? – Beyers Feb 11 '14 at 19:27
  • I never expected someone to do any ground work for me... My other comment wasn't clear enough I guess. I meant there is too many things that I would need to include in order to make a full fiddle considering the loading bar is in a modal, my controller isn't in app.js but another .js file and I have another controller for my modal,etc. Reproduicing this problem on a jsfiddle would take way more time then I can spare. As much as I'd like to provide a jsFiddle, all I can do is show the part of the code concerned. I'm hoping more for someone who had a similar problem that found a solution to this – snaplemouton Feb 11 '14 at 20:32
  • 2
    Post a minimum fiddle to reproduce the issue. – Matjaz Lipus Feb 14 '14 at 13:20
  • Any luck with this ? I'm facing same issue ! – Jalal El-Shaer Nov 14 '16 at 13:32
  • @JalalEl-Shaer , sorry, this issue is pretty old and I do not remember whether or not I got this fixed. – snaplemouton Nov 14 '16 at 16:11
  • @snaplemouton actually, I got it working from the "live working example" you mentioned. I simply copied the html and everything worked perfectly. It seems the problem is in the named parameter "file" rather than "flow". – Jalal El-Shaer Nov 15 '16 at 06:31

4 Answers4

1

If you are testing this locally, then your uploads should take less than a second. Flow.js has config parameter named progressCallbacksInterval, if you set it to high, then you won't be able to see any progress. Try setting this to 0, this means that on every progress event view will be updated.

Aidas
  • 369
  • 4
  • 7
  • I missed that config parameter in the documentation. Unfortunately, it still doesn't work. :( It looks more like an angular problem then a problem with Flow. The upload is being updated at the good rate, it's really just the ng-style that doesn't update the style in real time. – snaplemouton Feb 21 '14 at 14:44
  • If you are using Angular 1.1.5, then upgrading it to the latest ~1.2 might fix the problem – Aidas Feb 22 '14 at 09:21
1

You should use the file.progress as follows when setting the percentage:

file.progress() * 100
0

Without looking at your code or a fiddle that exemplifies the issue I can only think of a few possibilities:

Remember that Angular will only update your view when the model values change. So what you could do is create a model property, say

$scope.uploadProgress

and use $timeout (or $interval as of Angular 1.2) to update it, then when the upload finishes you halt its execution.

Then after you have a periodically updated property, you bind your view to that:

 <div class="progress progress-striped" ng-class"{active: file.isUploading()}">
   <div class="progress bar" role="progressbar" ng-style="{'width' : uploadProgress + '%'}"></div>
</div>

I believe the problem is that Angular is not evaluating the change of (file.sizeUploaded() / file.size * 100), at least I feel it shouldn't do that, you should update a property and angular should digest it.

Let me know how it goes so I can update my answer if this doesn't work.

You could also try watching a property and creating a function that returns its value, then you bind the div to that value:

//this object has all the info about the upload
$scope.uploadObject = {
    uploadedProgress: 0
}

$scope.barStyle = function() {
        return {
            width: $scope.uploadObject.uploadedProgress + '%',
            color: "#FFF" //Any property you may want to add
        };
};

$scope.$watch("uploadObject", $scope.barStyle);  

Then you update your view to reflect this change:

<div class="progress progress-striped" ng-class"{active: file.isUploading()}">
   <div class="progress bar" role="progressbar" ng-style="barStyle()"></div>
</div>
arg20
  • 4,893
  • 1
  • 50
  • 74
  • I tried using $timeout and it is still doing the same behavior. :s The ng-style isn't updating the style in real time but the value in ng-style is updating in real time. – snaplemouton Feb 17 '14 at 15:25
  • @snaplemouton I updated my answer with something else you could try. – arg20 Feb 19 '14 at 11:11
  • Tried your updated answer and it still does the same behavior. :( The value is updating correctly, but ng-style isn't updating the style in real time. – snaplemouton Feb 21 '14 at 14:47
0

I think the problem could be what me and my friends had a while back with image uploads. The problem, is that the client tracks the first 1% of an entire upload event as the time it takes for the file to leave the client and arrive at the server side.

The remaining 99% is the actual processing of said file on the server side, and returning it to the client. Since our server wasn't emitting events on that progress to the client (if it did, we could then properly track its progress), we were standing still at 1% for quite some time and then instantly jumping up to 100% as the file came back to the client.

The way we rectified this is by putting the image processing on the server side in a background job, and simply bumped up the factor of the currently uploaded size (in your case file.sizeUploaded()) by 100. This rendered a fluid progress bar for the first portion of the event, the event that's actually interesting for your everyday user.

The rest of the process is moved to a background job and we then keep a local copy of the uploaded file (through the various HTML5 Data API's) to be able to present the image to the user. This way we decouple the event from the server in a sense, and can go on our merry business.

Now, this is all well and good - but I'm not sure if this affects you in any way or form. I'm not even sure if flow.js already does this by default, because XHR2 Progress Events alone don't track the server side of things. So it would make sense for a library to already do this, as there is no way you would build a library like flow.js and depend on the server emitting events (well I suppose there is a way).

In any case, could you try bumping up the factor by 100 and see what results you get? I'm curious as to what the results may be, and if we have in fact been sitting in the same boat.

Good luck : )

  • It does make the bar show more then a tiny little bar, but if I bump it by * 100, when the file is done, it reaches 10000%. Also, if the user ever stop the file download, it reaches > 100% without being done. The file doesn't go to the server side. It's all done on the client side and it build a file on my client side that I can send to my server afterward. – snaplemouton Feb 17 '14 at 15:01
  • I see. Then its a completely different scenario than the one I proposed, I believe you can disregard from my post. Worth a shot! –  Feb 17 '14 at 15:05