Mike Sav
Mike Sav

Reputation: 15291

TypeScript / Angular2 - EXCEPTION: TypeError: Cannot read property 'push' of undefined

I am continuing to teach myself TypeScript and Angular2 and I am still hating it but I must perserver... anyway, I have a Component, that loads a JSON data from a REST service. This JSON data is in a very complex so I wish to break it down and when loading I wish to assign some of the JSON to an array that is of a certain type I have defined. Here is my type... I am listing information of the schools my users went to...

    export class UserSchool {

        constructor (
            public schoolId: number,
            public yearRange: string,
            public schoolName: string
        ) {
            this.schoolId = schoolId;
            this.yearRange = yearRange;
            this.schoolName = schoolName;
        }
    }

Now here is my Component,

import {Component, OnInit} from 'angular2/core';
import {UserData} from '../../services/user-data/UserData';
import {UserSchool} from '../../types/types';
import {Observable} from 'rxjs';

@Component({
    selector: 'profile',
    template: require('app/components/profile/profile.html'),
    providers: [],
    directives: [],
    pipes: []
})

export class Profile implements OnInit {

    userPhotos: any;
    userInfo: any;
    gapageName: string;
    albums: string[];
    userData: any;
    userSchools: UserSchool[];

    constructor(private userData:UserData) {
        this.userSchools = [];
    }

    ngOnInit() {
        // Use forkJoin as we don't need order in the calls
        Observable.forkJoin([
            this.userData.getUserPhotos('123456'),
            this.userData.getUserInfo()]).subscribe(t=> {
            this.userPhotos = t[0];
            this.userInfo = t[1];
            this.gapageName = this.userPhotos.gapageName;

           /*                    
           this.userInfo.data[0].items[0].entries is [Object, Object]
            each item is like so:
            {
            id: 665
            text: "2005 - 2010"
            title: "TownSchool For Bad Children"
            } 
            */
            this.userInfo.data[0].items[0].entries.forEach(function (a) {
                this.userSchools.push(a); // we get problems here...
            });

        });    
    }
}

when I try to loop through the JSON 'this.userInfo.data[0].items[0].entries' from my feed and push it to an array or types 'UserSchool' I get an error! EXCEPTION: TypeError: Cannot read property 'push' of undefined: I thought by adding the this.userSchools = []; to my constructor would get rid of this problem but it doesn't. Then I thought my scoping may be a problem, so in my forEach I tried:

this.userInfo.data[0].items[0].entries.forEach(function (a) {
    this.parent.userSchools.push(a); // still get an error
});

So can someone please tell me why I can't push to my object array? Many thanks in advance!

Upvotes: 0

Views: 3985

Answers (1)

Thierry Templier
Thierry Templier

Reputation: 202196

You should use arrow functions for the callback you provide to the forEach method to be able to use lexical this:

this.userInfo.data[0].items[0].entries.forEach((a) => {
  this.userSchools.push(a); // we get problems here...
});

In your case, this doesn't correspond to the instance of the component...

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.

Upvotes: 2

Related Questions