Skip to content
This repository was archived by the owner on Mar 17, 2025. It is now read-only.

Commit ef27fce

Browse files
committed
Add polyfil for angular 1.3.x/ES6 style promises.
Angular 1.3.x introduced ES6 style promises. These often provide much cleaner / more concise code. This commit provides a polyfill for that functionality that will use angulars implementation if available.
1 parent 5ad18b0 commit ef27fce

File tree

2 files changed

+93
-13
lines changed

2 files changed

+93
-13
lines changed

src/utils.js

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,29 @@
2525

2626
.factory('$firebaseUtils', ["$q", "$timeout", "firebaseBatchDelay",
2727
function($q, $timeout, firebaseBatchDelay) {
28+
29+
// ES6 style promises polyfill for angular 1.2.x
30+
// Copied from angular 1.3.x implementation: https://github.com/angular/angular.js/blob/v1.3.5/src/ng/q.js#L539
31+
function Q(resolver) {
32+
if (!angular.isFunction(resolver)) {
33+
throw new Error('missing resolver function');
34+
}
35+
36+
var deferred = $q.defer();
37+
38+
function resolveFn(value) {
39+
deferred.resolve(value);
40+
}
41+
42+
function rejectFn(reason) {
43+
deferred.reject(reason);
44+
}
45+
46+
resolver(resolveFn, rejectFn);
47+
48+
return deferred.promise;
49+
}
50+
2851
var utils = {
2952
/**
3053
* Returns a function which, each time it is invoked, will pause for `wait`
@@ -220,21 +243,14 @@
220243
});
221244
},
222245

223-
defer: function() {
224-
return $q.defer();
225-
},
246+
defer: $q.defer,
226247

227-
reject: function(msg) {
228-
var def = utils.defer();
229-
def.reject(msg);
230-
return def.promise;
231-
},
248+
reject: $q.reject,
232249

233-
resolve: function() {
234-
var def = utils.defer();
235-
def.resolve.apply(def, arguments);
236-
return def.promise;
237-
},
250+
resolve: $q.when,
251+
252+
//TODO: Remove false branch and use only angular implementation when we drop angular 1.2.x support.
253+
promise: angular.isFunction($q) ? $q : Q,
238254

239255
makeNodeResolver:function(deferred){
240256
return function(err,result){

tests/unit/utils.spec.js

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,3 +254,67 @@ describe('$firebaseUtils', function () {
254254
});
255255

256256
});
257+
258+
describe('#promise (ES6 Polyfill)', function(){
259+
260+
var status, result, reason, $utils, $timeout;
261+
262+
function wrapPromise(promise){
263+
promise.then(function(_result){
264+
status = 'resolved';
265+
result = _result;
266+
},function(_reason){
267+
status = 'rejected';
268+
reason = _reason;
269+
});
270+
}
271+
272+
beforeEach(function(){
273+
status = 'pending';
274+
result = null;
275+
reason = null;
276+
});
277+
278+
beforeEach(module('firebase',function($provide){
279+
$provide.decorator('$q',function($delegate){
280+
//Forces polyfil even if we are testing against angular 1.3.x
281+
return {
282+
defer:$delegate.defer,
283+
all:$delegate.all
284+
}
285+
});
286+
}));
287+
288+
beforeEach(inject(function(_$firebaseUtils_, _$timeout_){
289+
$utils = _$firebaseUtils_;
290+
$timeout = _$timeout_;
291+
}));
292+
293+
it('throws an error if not called with a function',function(){
294+
expect(function(){
295+
$utils.promise();
296+
}).toThrow();
297+
expect(function(){
298+
$utils.promise({});
299+
}).toThrow();
300+
});
301+
302+
it('calling resolve will resolve the promise with the provided result',function(){
303+
wrapPromise(new $utils.promise(function(resolve,reject){
304+
resolve('foo');
305+
}));
306+
$timeout.flush();
307+
expect(status).toBe('resolved');
308+
expect(result).toBe('foo');
309+
});
310+
311+
it('calling reject will reject the promise with the provided reason',function(){
312+
wrapPromise(new $utils.promise(function(resolve,reject){
313+
reject('bar');
314+
}));
315+
$timeout.flush();
316+
expect(status).toBe('rejected');
317+
expect(reason).toBe('bar');
318+
});
319+
320+
});

0 commit comments

Comments
 (0)