Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 - How to call a typescript function inside of an addEventListener handler function?

I'm trying to call another typescript function (of any kind) inside of a handler function added to spans on a page. When I do this, the handler function works fine and will do basic things such as set variables, console.log, etc. However, when trying to call a function of any kind it will throw an error of 'Cannot read property functionName of undefined'. So for example, here is code that works:

addListenter() {
if (!this.addListenerFired) {
  let iterateEl = this.el.nativeElement.querySelectorAll('span');
  for (let i = 0; i < iterateEl.length; i++) {
    iterateEl[i].addEventListener('click', this.showExcerptInfo);
  }
  this.addListenerFired = true;
}
showExcerptInfo (): void {
  this.selectedExcerptId = event.srcElement.id;
  console.log(this.selectedExcerptId);
}

However, if I change the handler function to do the following (or call any function located anywhere, even in the same component) it will not work and throws the error:

showExcerptInfo () {
  let excerpt = this.excerptsService.getExcerpt(this.selectedExcerptId);
}

Any clues as to why this is happening and/or how it can be resolved?

like image 246
Jason Simpson Avatar asked Jan 11 '17 08:01

Jason Simpson


People also ask

How do you call a function inside addEventListener?

When you set up a callback, you want to pass the function itself and not the result of calling it. So use the function name but don't put the parentheses after it: button. addEventListener('click', changeColor);

How do I add multiple functions in addEventListener?

We can invoke multiple functions on a single event listener without overwriting each other. To do this we simply call the addEventListener() method more than once with a different function. In the example above, we add another event listener for the same event on the same button.

What is this inside addEventListener?

Every scope in JavaScript has a this object that represents the calling object for the function. That's the reason why this inside addEventListener callback is invoked on the context of the current element instead of the global object. Refer below code for more clear understanding: function sayNameForAll() { console.

What is the benefit of using the addEventListener method instead of declaring an event as an attribute?

addEventListener() has multiple advantages: Allows you to register unlimited events handlers and remove them with element. removeEventListener() . Has useCapture parameter, which indicates whether you'd like to handle event in its capturing or bubbling phase.


2 Answers

You need to take care that this keeps pointing at the current class instance:

iterateEl[i].addEventListener('click', this.showExcerptInfo.bind(this));

alternatively you can use

iterateEl[i].addEventListener('click', (evt) => this.showExcerptInfo(evt));
like image 119
Günter Zöchbauer Avatar answered Oct 05 '22 03:10

Günter Zöchbauer


this not pointing to your class. there is more 2 ways to do it with keeping 'this' without 'bind':

iterateEl[i].addEventListener('click', (event) => this.showExcerptInfo(event));

or:

iterateEl[i].addEventListener('click', this.showExcerptInfo);

showExcerptInfo: (any) => void = (event:any):void => {
  this.selectedExcerptId = event.srcElement.id;
  console.log(this.selectedExcerptId);
}
like image 41
YairTawil Avatar answered Oct 05 '22 03:10

YairTawil