-
Notifications
You must be signed in to change notification settings - Fork 0
/
angularFirebasePatch.js
126 lines (102 loc) · 2.82 KB
/
angularFirebasePatch.js
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
angular.module('AngularFirebase', [])
.run(['$timeout', '$q', function($timeout, $q){
var angularWrap = $timeout;
var FirebaseCaller = function(functionToCall, type, params, callback) {
// Create an array to hold our Firebase refs and clean them later on
if (!this.refsArray) {
this.refsArray = [];
}
var defer = $q.defer();
var defaultParams;
// keep a handy reference to ref
var ref;
// Read mode : Firebase expect a callback with the snapshot
if (type == "read") {
var makeReadFn = function(callback) {
return function(snapshot) {
var args = arguments;
angularWrap(function(){
// Callback is for "on" events
if (callback) {
callback.apply(null, args);
}
defer.resolve(snapshot);
});
};
};
/// Generate a new fn to clear it later
var readFn = makeReadFn(callback);
defaultParams = [
readFn
];
// Add an error handler
defaultParams.push(function(error){
defer.reject(error);
});
// Keep that against the ref to clean it later
this.refsArray.push({
type: params[0], // is the type
fn: readFn,
context: this
});
}
// Write mode : callback is just passed an error object (null if no error)
else {
defaultParams = [
function(error) {
angularWrap(function(){
if (callback) {
callback(error);
}
if (error != null) {
defer.reject(error);
}
else {
if (functionToCall == "push") {
ref.data = params[0];
}
defer.resolve(ref);
}
});
}
];
}
// params must be an array to be concatenated with our defaultParams and passed
// to .apply
if (params) {
defaultParams = params.concat(defaultParams);
}
// We're gonna provide as context (this) to clear listeners later
if (type === "read") {
defaultParams.push(this);
}
// This must be set by callers to the Firebase instance
ref = this[functionToCall].apply(this, defaultParams);
return defer.promise;
};
// Let's patch Firebase to wrap dat shit in Angular
Firebase.prototype = angular.extend(Firebase.prototype, {
onceAngular: function(eventName) {
return FirebaseCaller.apply(this, ["once", "read", [eventName]]);
},
onAngular: function(eventName, callback) {
return FirebaseCaller.apply(this, ["on", "read", [eventName], callback]);
},
pushAngular: function(data) {
return FirebaseCaller.apply(this, ["push", "write", [data]]);
},
setAngular: function(data) {
return FirebaseCaller.apply(this, ["set", "write", [data]]);
},
removeAngular: function() {
return FirebaseCaller.apply(this, ["remove", "write", []]);
},
cleanListeners: function() {
var _this = this;
this.refsArray.forEach(function(refObject){
_this.off(refObject.type, refObject.fn, refObject.context);
});
return this;
}
});
}]);