diff --git a/firebase-query.html b/firebase-query.html
index c4e9cce..d503f83 100644
--- a/firebase-query.html
+++ b/firebase-query.html
@@ -292,6 +292,12 @@
});
}
+ // this allows us to just call the addition of event listeners only once.
+ // __queryChanged is being called thrice when firebase-query is created
+ // 1 - 2. query property computed (null, undefined)
+ // 3. when attached is called (this.query, this.query)
+ // need help to fix this so that this function is only called once
+
if (query) {
if(this._onOnce){ // remove handlers before adding again. Otherwise we get data multiplying
query.off('child_added', this.__onFirebaseChildAdded, this);
@@ -300,21 +306,12 @@
query.off('child_moved', this.__onFirebaseChildMoved, this);
}
- this._onOnce = true;
-
- /* We want the value callback to batch load the initial data,
- * then let child_added take over for subsequent changes.
- */
- this.__initialLoadDone = false;
-
- /* Don't use query.once() as we need to be able to cancel
- * the callback if the query changes
- */
- query.on('value', this.__onFirebaseValue, this.__onError, this);
- query.on('child_added', this.__onFirebaseChildAdded, this.__onError, this);
- query.on('child_removed', this.__onFirebaseChildRemoved, this.__onError, this);
- query.on('child_changed', this.__onFirebaseChildChanged, this.__onError, this);
- query.on('child_moved', this.__onFirebaseChildMoved, this.__onError, this);
+ this._onOnce = true;
+ this._query = query
+
+ // does the on-value first
+ query.off('value', this.__onFirebaseValue, this)
+ query.on('value', this.__onFirebaseValue, this.__onError, this)
}
},
@@ -335,6 +332,7 @@
snapshot.forEach(function(childSnapshot) {
var key = childSnapshot.key;
var value = this.__valueWithKey(key, childSnapshot.val())
+
this.__map[key] = value;
data.push(value)
}.bind(this))
@@ -342,28 +340,41 @@
this.set('data', data);
}
- /* Now let child_added deal with subsequent changes */
- this.query.off('value', this.__onFirebaseValue, this);
- this.__initialLoadDone = true;
+ const query = this.query
+
+ query.off('value', this.__onFirebaseValue, this)
+
+ // ensures that all events are called once
+ query.off('child_added', this.__onFirebaseChildAdded, this);
+ query.off('child_removed', this.__onFirebaseChildRemoved, this);
+ query.off('child_changed', this.__onFirebaseChildChanged, this);
+ query.off('child_moved', this.__onFirebaseChildMoved, this);
+
+ query.on('child_added', this.__onFirebaseChildAdded, this.__onError, this);
+ query.on('child_removed', this.__onFirebaseChildRemoved, this.__onError, this);
+ query.on('child_changed', this.__onFirebaseChildChanged, this.__onError, this);
+ query.on('child_moved', this.__onFirebaseChildMoved, this.__onError, this);
},
__onFirebaseChildAdded: function(snapshot, previousChildKey) {
var key = snapshot.key;
- if (this.__initialLoadDone) {
- var value = snapshot.val();
- var previousChildIndex = this.__indexFromKey(previousChildKey);
+ // check if the key-value pair already exists
+ if (this.__indexFromKey(key) >= 0) return
- this._log('Firebase child_added:', key, value);
+ var value = snapshot.val();
+ var previousChildIndex = this.__indexFromKey(previousChildKey);
- value = this.__snapshotToValue(snapshot);
+ this._log('Firebase child_added:', key, value);
- this.__map[key] = value;
- this.splice('data', previousChildIndex + 1, 0, value);
- }
+ value = this.__snapshotToValue(snapshot);
+
+ this.__map[key] = value;
+ this.splice('data', previousChildIndex + 1, 0, value);
},
__onFirebaseChildRemoved: function(snapshot) {
+
var key = snapshot.key;
var value = this.__map[key];
@@ -373,7 +384,11 @@
this.__map[key] = null;
this.async(function() {
this.syncToMemory(function() {
- this.splice('data', this.__indexFromKey(key), 1);
+ // this only catches already deleted keys (which will return -1)
+ // at least it will not delete the last element from the array (this.splice('data', -1, 1))
+ if (this.__indexFromKey(key) >= 0) {
+ this.splice('data', this.__indexFromKey(key), 1);
+ }
});
});
}