Demo: http://datadoodler.github.io/ts-05-progressbar-bound-to-promise-array
Source: https://github.com/datadoodler/ts-05-progressbar-bound-to-promise-array/
Progressbar Bound to Promise Array
The application is periodically caching images (asynchronously). Whenever images are being pulled over the wire we want to show the progressbar (angular bootstrap directive) and the percentage complete of the images. Progressbar doesn’t need to show the percent downloaded of a single image, but the percentage of the list of images that have completed (or failed) download.
promise-maker.service.js
A simple factory that simulates an asynchronous method (such as retrieving images via ajax call).1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18.factory('promiseMaker', function ($q, $timeout) {
var promiseMaker = {};
promiseMaker.getVolley = function (cb) {
var rtrn = [];
// Create 10 promises
for(var i=0;i<10;i++){
rtrn.push($q.when($timeout(function () {
console.log('new', new Date())
}, 1000 + (Math.random() * 3000))));
}
return rtrn;
};
return promiseMaker;
});
controller
The getPromises function makes the call to the service, and fills the promises array with the returned promises. The number of promises returned is held in originalPromiseCount and used as the denominator. As promises are resolved (successfully or unsuccessfully) they are popped off the array. The length of this array is the denominator of percentage complete.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38function ctrl1(promiseMaker) {
var vm = this;
vm.promises = [];
vm.showbar = false;
vm.originalPromiseCount = 0;
vm.getPromises = function () {
vm.originalPromiseCount = 0;
var newPromises = promiseMaker.getVolley();
vm.showbar = true;
vm.originalPromiseCount = newPromises.length;
newPromises.forEach(function (prom) {
pushPromise(prom)
})
};
vm.getPercentComplete = function () {
if (vm.promises.length === 0) {
return 0;
}
return 100 * (vm.originalPromiseCount - vm.promises.length) / vm.originalPromiseCount;
};
function pushPromise(prom) {
prom.finally(function () {
// When this promise is resolved, remove it.
removePromise(prom);
});
vm.promises.push(prom);
}
function removePromise(prom) {
vm.promises.pop();
vm.promises.length === 0 ? vm.showbar = false : vm.showbar = true;
}
return vm;
}
Dependencies
(Note: these dependencies are statically loaded in the vendor_local directory of this techsketch to enable disconnected editing and viewing on demo site)
- angular AngularJS v1.3.20
- angular-animate AngularJS v1.3.20
- angular-ui-bootstrap Version: 0.12.1 - 2015-02-20
- bootstrap css (an custom edited version of v3.3.6)
Demo
http://datadoodler.github.io/ts-05-progressbar-bound-to-promise-array/