1

I am building really simple Angular2 that talks to Firebase by using "firebase-angular2" npm module. I managed to make it post to Firebase without problems.

Problems:

  1. I cant make "items" to get values from "itemsarr", I get error: Uncaught TypeError: Cannot set property 'items' of undefined. I tried setting directly: this.items.push(records.val());, but I get same error.
  2. On line 14 I see all items in array, but it lists in console array everytime it is updated, so if I have 50 items, it will list 50 times in console. I know I should move it outside, but look at question 3.
  3. On line 16 I do not see anything in itemsarr, it is empty?!

Code:

1 var itemsarr = [];
2 @Component({
     template:`
        <li *ngFor="#item of items">
          {{item.title}}
        </li>
     `
  })
3 export class AppComponent {
4
5   items:Array<string>;
6 
7   constructor() {
8     
9
10       myFirebaseRef.on('child_added', function(childSnapshot, prevChildKey) {
11          childSnapshot.forEach(function(records) {
12             this.items = itemsarr.push(records.val());
13          });
14          console.log(itemsarr)
15      });
16      console.log(itemsarr)
17     }
18   }
19 }

SOLUTION (thanks Thierry)

I needed to set "=[]" to items first, and then transform to arrow functions and then all worked without problems. Didn't know that arrow functions and this are connected in that way.

1 
2 @Component({
     template:`
        <li *ngFor="#item of items">
          {{item.title}}
        </li>
     `
  })
3 export class AppComponent {
4
5   items:Array<string>=[];
6 
7   constructor() {
8     
9
10       myFirebaseRef.on('child_added', (childSnapshot, prevChildKey) => {
11          childSnapshot.forEach((records) => {
12             this.items.push(records.val());
13          });
14      
15      });
16 
17     }
18   }
19 }
Milan Milanovic
  • 433
  • 1
  • 7
  • 14

2 Answers2

1

You should use arrow functions to be able to use the this keyword corresponding to the component itself.

export class AppComponent {
  items:Array<string>;

  constructor() {
    myFirebaseRef.on('child_added', (childSnapshot, prevChildKey) => {
      childSnapshot.forEach((records) => {
        this.items = itemsarr.push(records.val());
      });
      console.log(itemsarr)
    });
    console.log(itemsarr);
  }
}

See this link for more hints about the lexical this of arrow functions: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions.

Hope it helps you, Thierry

Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
0

Use

childSnapshot, prevChildKey = { ... }

records => { ... }

instead of

function(childSnapshot, prevChildKey) { ... }

function(records) { ... }
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567