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?
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);
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.
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.
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.
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));
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With