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

Commit b8c5843

Browse files
author
Jacob Wenger
committed
Merge pull request #531 from jamestalmage/es6-style-promises
Es6 style promises
2 parents 7f8ca79 + 293cbd4 commit b8c5843

File tree

4 files changed

+124
-38
lines changed

4 files changed

+124
-38
lines changed

src/FirebaseAuth.js

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -248,24 +248,28 @@
248248
*/
249249
_routerMethodOnAuthPromise: function(rejectIfAuthDataIsNull) {
250250
var ref = this._ref;
251-
var deferred = this._q.defer();
252251

253-
function callback(authData) {
254-
if (authData !== null) {
255-
deferred.resolve(authData);
256-
} else if (rejectIfAuthDataIsNull) {
257-
deferred.reject("AUTH_REQUIRED");
258-
} else {
259-
deferred.resolve(null);
252+
return this._utils.promise(function(resolve,reject){
253+
function callback(authData) {
254+
// Turn off this onAuth() callback since we just needed to get the authentication data once.
255+
ref.offAuth(callback);
256+
257+
if (authData !== null) {
258+
resolve(authData);
259+
return;
260+
}
261+
else if (rejectIfAuthDataIsNull) {
262+
reject("AUTH_REQUIRED");
263+
return;
264+
}
265+
else {
266+
resolve(null);
267+
return;
268+
}
260269
}
261270

262-
// Turn off this onAuth() callback since we just needed to get the authentication data once.
263-
ref.offAuth(callback);
264-
}
265-
266-
ref.onAuth(callback);
267-
268-
return deferred.promise;
271+
ref.onAuth(callback);
272+
});
269273
},
270274

271275
/**

src/firebase.js

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -128,16 +128,18 @@
128128
}
129129
applyLocally = !!applyLocally;
130130

131-
var def = $firebaseUtils.defer();
132-
ref.transaction(valueFn, function(err, committed, snap) {
133-
if( err ) {
134-
def.reject(err);
135-
}
136-
else {
137-
def.resolve(committed? snap : null);
138-
}
139-
}, applyLocally);
140-
return def.promise;
131+
return new $firebaseUtils.promise(function(resolve,reject){
132+
ref.transaction(valueFn, function(err, committed, snap) {
133+
if( err ) {
134+
reject(err);
135+
return;
136+
}
137+
else {
138+
resolve(committed? snap : null);
139+
return;
140+
}
141+
}, applyLocally);
142+
});
141143
},
142144

143145
$asObject: function () {

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
@@ -253,3 +253,67 @@ describe('$firebaseUtils', function () {
253253
});
254254

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

0 commit comments

Comments
 (0)