Skip to content
This repository was archived by the owner on May 19, 2025. It is now read-only.
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 42 additions & 27 deletions firebase-query.html
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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)
}
},

Expand All @@ -335,35 +332,49 @@
snapshot.forEach(function(childSnapshot) {
var key = childSnapshot.key;
var value = this.__valueWithKey(key, childSnapshot.val())

this.__map[key] = value;
data.push(value)
}.bind(this))

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];

Expand All @@ -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);
}
});
});
}
Expand Down