Reputation: 405
I'm trying to push Firebase database values into a new array through an Ionic typescript file.
The problem is, I keep getting the error:
Error: Uncaught (in promise): TypeError: Cannot read property 'empList' of undefined
I can't really understand why because I'm still learning Typescript and have no idea what to do.
The firebase JSON looks like this:
- users
- hJfEgXkyaKPckchL3kx8rpZ58Ew2
-LV6c8E5rRD4_mQqsb6Q
- name: "Emily Blunt"
- points: 20
- grade: 12
export class Tab1Page {
name: string;
grade: number;
points: number;
empList: Array<{name: string, grade: number, points: number}> = [];
constructor() {
const usersRef = firebase.database().ref('/users/');
const ref = usersRef.orderByChild('points');
ref.once('value').then(function(snap) {
snap.forEach(function (childSnap) {
const pkey = childSnap.key;
// returns 'hJfEgXkyaKPckchL3kx8rpZ58Ew2'
const keyRef = firebase.database().ref('/users/' + pkey);
const ref2 = keyRef.orderByChild('name');
ref2.once('value').then(function(snap) {
snap.forEach(function (childSnap) {
const key = childSnap.key;
//returns -LV6c8E5rRD4_mQqsb6Q
const firebaseRef = firebase.database().ref('/users/' + pkey + '/' + key);
firebaseRef.once('value').then(function(snapshot) {
const name = snapshot.val().name;
const grade = snapshot.val().grade;
const points = snapshot.val().points;
// returns 'Emily Blunt', 12, 20
this.empList.push({
name: name,
grade: grade,
points: points
});
});
});
});
});
});
}
}
Any help would be deeply appreciated.
Upvotes: 1
Views: 72
Reputation: 8686
The cause of your problem is a bad scoping of the this
object in your firebase
callback function. It actually refers to a Firebase.Promise. You need to save a reference to the this
referring to your class, and then use this in the firebase
callback :
export class Tab1Page {
name: string;
grade: number;
points: number;
empList: Array<{name: string, grade: number, points: number}> = [];
constructor() {
const usersRef = firebase.database().ref('/users/');
const ref = usersRef.orderByChild('points');
const self = this;
ref.once('value').then(function(snap) {
snap.forEach(function (childSnap) {
const pkey = childSnap.key;
// returns 'hJfEgXkyaKPckchL3kx8rpZ58Ew2'
const keyRef = firebase.database().ref('/users/' + pkey);
const ref2 = keyRef.orderByChild('name');
ref2.once('value').then(function(snap) {
snap.forEach(function (childSnap) {
const key = childSnap.key;
//returns -LV6c8E5rRD4_mQqsb6Q
const firebaseRef = firebase.database().ref('/users/' + pkey + '/' + key);
firebaseRef.once('value').then(function(snapshot) {
const name = snapshot.val().name;
const grade = snapshot.val().grade;
const points = snapshot.val().points;
// returns 'Emily Blunt', 12, 20
self.empList.push({
name: name,
grade: grade,
points: points
});
});
});
});
});
});
}
}
You can see this another SO answer to have more details on the this
binding : How does the this keword work
Upvotes: 3