Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 867
Sleeper9 Avatar asked Apr 27 '16 08:04

Sleeper9


2 Answers

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:

  • https://basarat.gitbooks.io/typescript/content/docs/tips/bind.html
like image 99
Thierry Templier Avatar answered Oct 26 '22 09:10

Thierry Templier


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
}
like image 41
Post Impatica Avatar answered Oct 26 '22 09:10

Post Impatica