1

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.

1
  • show your component page where you are using empList? Commented Jan 2, 2019 at 8:30

1 Answer 1

3

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.