In Polymer 1.x I am trying to push data from my database to an array, but for whatever reason, it suddenly stopped working.
When running this code
ready: function(){
var leserbriefRef = firebase.database().ref('leserbriefe');
leserbriefRef.on('value', function(snap) {
var n = snap.child('numLeserbriefe').val();
console.log(n);
this.lbriefe = [];
for(var i=0; i<n; i++){
this.push("lbriefe", snap.child('l'+(n - 1 - i)).val());
}
});
}
I get this error message:
firebase.js:283 Uncaught TypeError: this.push is not a function
I don't know why. Earlier this week it still worked.
This is a common gotcha among js beginners, basically the usage of the this
keyword. The context of the this
variable inside the anonymous function is not the one you intended (in this case, the element). To solve this, you can use closures[1], .bind
[2], or the newer ES2015 arrow functions[3].
Closure
ready: function() {
// assign this to self
var self = this;
var leserbriefRef = firebase.database().ref('leserbriefe');
leserbriefRef.on('value', function(snap) {
var n = snap.child('numLeserbriefe').val();
console.log(n);
self.lbriefe = [];
for(var i = 0; i < n; i++){
self.push("lbriefe", snap.child('l'+(n - 1 - i)).val());
}
});
}
.bind
ready: function() {
var leserbriefRef = firebase.database().ref('leserbriefe');
leserbriefRef.on('value', function(snap) {
var n = snap.child('numLeserbriefe').val();
console.log(n);
this.lbriefe = [];
for(var i = 0; i < n; i++){
this.push("lbriefe", snap.child('l'+(n - 1 - i)).val());
}
}.bind(this)); // bind this keyword to element's
}
ES2015 arrow function (might as well go full ES2015)
ready() {
const leserbriefRef = firebase.database().ref('leserbriefe');
leserbriefRef.on('value', (snap) => { // arrow functions!
const n = snap.child('numLeserbriefe').val();
console.log(n);
this.lbriefe = [];
for(let i = 0; i < n; i++){
this.push("lbriefe", snap.child(`l${n - 1 - i}`).val());
}
});
}
Sources:
[1] https://developer.mozilla.org/en/docs/Web/JavaScript/Closures
[2] https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind
[3] https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions
well you have to watch for this
binding, since the scope of this
is changes inside functions.
ready: function(){
var leserbriefRef = firebase.database().ref('leserbriefe');
leserbriefRef.on('value', function(snap) {
var n = snap.child('numLeserbriefe').val();
console.log(n);
this.lbriefe = [];
for(var i=0; i<n; i++){
this.push("lbriefe", snap.child('l'+(n - 1 - i)).val());
}
}.bind(this));
}