Sleeper9 Sleeper9 - 4 months ago 11
Javascript Question

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?

Answer

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:

Comments