Sleeper9
Sleeper9

Reputation: 1779

Angular2 'this' is undefined

I have a code that looks like this:

export class CRListComponent extends ListComponent<CR> implements OnInit {

    constructor(
        private router: Router,
        private crService: CRService) {
        super();
    }

    ngOnInit():any {
        this.getCount(new Object(), this.crService.getCount);
    }

The ListComponent code is this

@Component({})
export abstract class ListComponent<T extends Listable> {

    protected getCount(event: any, countFunction: Function){
        let filters = this.parseFilters(event.filters);
        countFunction(filters)
            .subscribe(
                count => {
                    this.totalItems = count;
                },
                error => console.log(error)
            );
    }

And the appropriate service code fragment from CRService is this:

getCount(filters) {
    var queryParams = JSON.stringify(
        {
            c : 'true',
            q : filters
        }
    );

    return this.createQuery(queryParams)
        .map(res => res.json())
        .catch(this.handleError);
}

Now when my ngOnInit() runs, I get an error:

angular2.dev.js:23925 EXCEPTION: TypeError: Cannot read property 'createQuery' of undefined in [null]

ORIGINAL EXCEPTION: TypeError: Cannot read property 'createQuery' of undefined

So basically, the this in the return this.createQuery(queryParams) statement will be null. Does anybody have an idea how is this possible?

Upvotes: 7

Views: 9011

Answers (2)

Post Impatica
Post Impatica

Reputation: 16413

To fix this error I yanked all the innards out of my function causing the error and threw it in another function then the error went away.

example:

I had this function with some code in it

this.globalListenFunc = renderer.listenGlobal('document', 'click', (event) => {
  // bunch of code to evaluate click event
  // this is the code that had the "this" undefined error
});

I pulled the code out and put it in an external public function, here's the finished code:

this.globalListenFunc = renderer.listenGlobal('document', 'click', (event) => {
  this.evaluateClick(event);
});

evaluateClick(evt: MouseEvent){
    // all the code I yanked out from above
}

Upvotes: 2

Thierry Templier
Thierry Templier

Reputation: 202266

The problem is located here:

gOnInit():any {
    this.getCount(new Object(), this.crService.getCount); // <----
}

Since you reference a function outside an object. You could use the bind method on it:

this.getCount(new Object(), this.crService.getCount.bind(this.crService));

or wrap it into an arrow function:

this.getCount(new Object(), (filters) => {
  return this.crService.getCount(filters));
});

The second approach would be the preferred one since it allows to keep types. See this page for more details:

Upvotes: 10

Related Questions