The concept of 'this' in TypeScript classes compared to JavaScript's scope

Is there a way to change the custom icon of a video when it is toggled between Play and Pause?

ngAfterViewInit() {
 const vdoCont = document.querySelector('.video-player');
 const vdo = vdoCont.querySelector('video');
    vdo.addEventListener('play', () => {
     console.log(this) // This "this" refers to the TypeScript class
     this.updateVdoIcon(this);
    });
    vdo.addEventListener('pause', () => {
     console.log(this) // Here "this" refers to typescript class
     this.updateVdoIcon(this);
    });
}

updateVdoIcon(videoElment: any) {
    console.log(videoElment); // I'm expecting this to be the video element instead of the TypeScript class
  }

I attempted to change arrow functions to JavaScript functions, but then I can't utilize my "updateVdoIcon" function.

vdo.addEventListener('play', function() {
      this.updateVdoIcon(this); // Property 'updateVdoIcon' does not exist on type 'HTMLVideoElement'
});

While I know I could use an anonymous function (as shown below) and update the icon there, what if I have a lot of code that I want to separate into a function?

vdo.addEventListener('play', function() {
 this.paused ? console.log('Play icon') : console.log('Pause icon')
});

Answer №1

When the event listener handler is triggered, it operates outside the Component's scope. This means that this does not refer to the component, but rather the control element.

To resolve this issue, you should bind your listener with this.

vdo.addEventListener('play', (function() {
      this.updateVdoIcon(this);
}).bind(this));

For more information, you can refer to the documentation here.


You can enhance clarity by breaking it down into a separate function call onClick.

onClick() {
  this.updateVdoIcon(this);
}

initialize() {
  vdo.addEventListener('play', this.onClick.bind(this));
}

Alternatively, you can store this as the component and pass it to the event listener.

let self = this;

vdo.addEventListener('play', function() {
      self.updateVdoIcon(this);
});

Answer №2

If you want to try a different approach, you can utilize the ElementRef to gain access to the element and then establish an event binding.

The code snippet can be found here: .

import { AfterViewInit, Component, ElementRef} from '@angular/core';

constructor(private elementRef:ElementRef) {}

ngAfterViewInit() {
  this.elementRef.nativeElement.querySelector('my-element')
                                .addEventListener('click', this.onClick.bind(this));
}

onClick(event) {
  console.log(event);
}

Answer №3

If you pass the event.currentTarget into the callback function, it will refer to the element where the event listener was defined:

vdo.addEventListener('play', (event) => {
     this.updateVdoIcon(event.currentTarget);
});

In this example, the reference to this is the lexical this within the arrow function. It captures the context of this from the lexical scope, specifically the class instance.

Answer №4

Below is the solution provided for you:

ngAfterViewInit() {
const videoContainer = document.querySelector('.video-player');
const video = videoContainer.querySelector('video');
const self = this;
   video.addEventListener('play', function(){
    console.log(this) // In this context, "this" refers to the typescript class
    self.updateVideoIcon(this);
   });
   video.addEventListener('pause', function(){
    console.log(this) // In this context, "this" refers to the typescript class
    self.updateVideoIcon(this);
   });

}

updateVideoIcon(videoElement: any) { console.log(videoElement); // The expected value here is the video element itself rather than the typescript class }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

"Authentication through Passport-twitter has encountered an issue as the request token was not located in the

Yesterday I encountered an issue on Heroku with Twitter login in Express, resulting in the following error: Error: failed to find request token in session at Strategy.<anonymous> (/app/node_modules/passport-twitter/node_modules/passport-oauth/li ...

Linking asynchronous AJAX requests using Angularjs

Currently in my AngularJS project, I have created a service with multiple functions that return promises. The AJAX Service I've Created: angular.module('yoApp') .factory('serviceAjax', function serviceAjax($http) { return ...

Is it possible to retrieve an array using axios?

Currently, I am exploring computed properties in Vue.js. One of the computed methods I am working on involves making a request to an axios API to retrieve an array after applying some logic within the promise. computed: { filteredTrips: function () { ...

Eliminating data type from union in Typescript

I have a specific type that I collect from various other types: type CustomType = { id: string; foo: (string | Type1)[]; bar: (string | Type2)[]; baz: string | Type3 | null; description: string | null; } I am interested in refining thi ...

Issue with border radius in MUI 5 affecting table body and footer elements

Currently, I am diving into a new project utilizing React version 18.2 and MUI 5.10.3 library. My main task involves designing a table with specific styles within one of the components. The table header should not display any border lines. The table body ...

Creating a dataset for D3 in JavaScript: A step-by-step guide

I am attempting to construct a graph similar to this: https://i.sstatic.net/USdyj.png. The graph represents a dependencies tree where each node has a list of elements it depends on as children (in a list), or a simple JSON structure with name and size info ...

Calculating the sum of values in a JSON array using a specific parameter in Typescript

A flat JSON array contains repetitive identifier, categoryId, and category: data: [ { "identifier": "data", "categoryId": "1", "category": "Baked goods", "product": "Aunt Hattie's", "price": "375" } ...

What sets apart the Jquery Function Template from the Method Template?

Can someone explain the difference between Jquery Function Templates and Method Templates and how to properly utilize them? Below is a snippet of a Function Template and Method Template, but what sets them apart? Function Template:- (function($){ $.f ...

The problem with RXJS pipe in Angular application is that it evaluates excessively, leading to eventual breakdown

I'm experiencing challenges when attempting to fork an Observable (that has been piped multiple times): subscribing to it in one place, and piping and subscribing to it in another place. I am facing 2 issues: The pipes are being evaluated multiple t ...

guide to utilizing npm/yarn with tsx react

I've recently made the switch to using TypeScript with React, but I'm encountering a problem. After installing certain packages from npm or yarn, I'm having trouble using them in my .tsx components. The error message suggests looking for @ty ...

Anticipate the occurrence of an event in Node.js

Is there a way to wait for an event in node js? In my bpmn workflow development, I need to execute the events step by step. Each script represents an event within the server that consists of multiple scripts. For example: 'use strict'; const Bpm ...

Error encountered while trying to display content in the rendering area

const Pages = () => { return ( <> <Box display="flex"> {window.location.pathname === "/profile" ? undefined : <Sidebar />} <Box flex={3}> <Navbar /> <Routes> {/* Cont ...

Angular not displaying input value correctly in first loop index

Hello, I am currently working on a rent calculator application using Angular. The app takes three inputs: total rent, annual rent increase amount, and the number of years to calculate for. One issue I am facing is that the for loop does not print the enter ...

Revamping the login interface for enhanced user

Whenever I attempt to login by clicking the login button, there seems to be an issue as it does not redirect me to any other page. Instead, I am left on the same page where I initially clicked the button. The intended behavior is for users to be redirected ...

Navigating Cross-Origin Resource Sharing (CORS) Challenges within

Currently in the process of developing an API utilizing our API server script and attempting to establish communication with the API on the IONIC framework application. Progress is being made, however, encountering a recurring issue with the cross-origin b ...

Guide to showcasing multiple paths of Firebase data on a single Angular page

I am working with a basic database structure that includes information about groups, events, and users. Here is an example: { "groups": { "123": { "name": "developers", "users": { "1": true }, "users_count": 1 } ...

The error message "Cannot send headers after they have already been sent to the client" is caused by attempting to set headers multiple

Although I'm not a backend developer, I do have experience with express and NodeJS. However, my current project involving MongoDB has hit a roadblock that I can't seem to resolve. Despite researching similar questions and answers, none of the sol ...

Jquery Issue: Safari Leaves Alert Messages Unclosed When Opening Next Alert

I am experiencing an issue in Safari Browser and need some help with the following scenarios (with Example). When I click a button to delete an account, an alert message pops up. This alert window has two actions - "OK" and "Cancel". If I click "OK", it r ...

It is necessary to sign out users when a specific database value is set to false

Whenever a value in the firebase database is false, I need to shut down the app for maintenance purposes. A problem arises when the user is already logged in, as the function does not trigger unless I reload the app. I am looking for a way to trigger the f ...

Tips on obtaining the element that was used as the event selector

I am facing a challenge with a specific issue. Within a div containing various elements, I have implemented a mouseover event. The issue arises when trying to target this particular div in the mouseover function, as there are multiple automatically genera ...