Issues arise when Angular properties become undefined following the initialization or OnInit functions

There seems to be a peculiar issue with the properties of an angular component that I have set up. It appears that these properties are losing their values after the initialization process. The component is essentially a basic HTML file containing a video player. (shown below)

<video width="200" controls="true" poster="" id="video">
    <source type="video/mp4" src="http://www.w3schools.com/html/mov_bbb.mp4">
</video>

Subsequently, in the typescript file of the component, I have experimented by initializing the property with a predefined value, creating it without a value and then assigning it in the constructor, and also by creating it without a value and assigning it in the onInit function. In all three scenarios, the value appears correct when logged in the console. However, at a later event, the value becomes undefined. Additionally, please note that the property has not been linked or bound to any specific elements.

Create properties with initial values

export class VideoPlayerComponent implements OnInit {

  timeStarted = 0;
  timePlayed = 0;
  duration = 0;
  video: HTMLVideoElement;

  constructor() {
    
  }


  ngOnInit(): void {
    //Values appear accurate when logged here
    console.log("Time Started: " + this.timeStarted);
    console.log("Time Played: " + this.timePlayed);
    console.log("Duration: " + this.duration);
    this.video = <HTMLVideoElement> document.getElementById("video");

    this.video.addEventListener("pause", this.videoStoppedPlaying);
    

  }
  
  videoStoppedPlaying(event) {
    //Value is undefined at this point
    console.log("Time Started: " + this.timeStarted);
    console.log("Time Played: " + this.timePlayed);
    console.log("Duration: " + this.duration);
  }
}

Create properties and assign in constructor

export class VideoPlayerComponent implements OnInit {

  timeStarted: number;
  timePlayed: number;
  duration: number;
  video: HTMLVideoElement;

  constructor() {
    this.timeStarted = 0;
    this.timePlayed = 0;
    this.duration = 0
    this.video = <HTMLVideoElement> document.getElementById("video");
  }


  ngOnInit(): void {
    //Values appear accurate when logged here
    console.log("Time Started: " + this.timeStarted);
    console.log("Time Played: " + this.timePlayed);
    console.log("Duration: " + this.duration);

    this.video.addEventListener("pause", this.videoStoppedPlaying);
    

  }

  videoStoppedPlaying(event) {
    //Value is undefined at this point
    console.log("Time Started: " + this.timeStarted);
    console.log("Time Played: " + this.timePlayed);
    console.log("Duration: " + this.duration);
  }

}

Create properties and assign in onInit

export class VideoPlayerComponent implements OnInit {

  timeStarted: number;
  timePlayed: number;
  duration: number;
  video: HTMLVideoElement;

  constructor() {
    
  }


  ngOnInit(): void {
    this.timeStarted = 0;
    this.timePlayed = 0;
    this.duration = 0
    this.video = <HTMLVideoElement> document.getElementById("video");
    //Values appear accurate when logged here
    console.log("Time Started: " + this.timeStarted);
    console.log("Time Played: " + this.timePlayed);
    console.log("Duration: " + this.duration);

    this.video.addEventListener("pause", this.videoStoppedPlaying);
    

  }

  videoStoppedPlaying(event) {
    //Value is undefined at this point
    console.log("Time Started: " + this.timeStarted);
    console.log("Time Played: " + this.timePlayed);
    console.log("Duration: " + this.duration);
  }

}

If anyone could shed some light on the possible reasons behind the disappearance of the value post-initialization and loading, it would be greatly appreciated.

Answer №1

The reason for this confusion is that the keyword this does not point to your VideoPlayerComponent component as expected; instead, it refers to this.video.
This discrepancy arises from the line of code:

this.video.addEventListener("pause", this.videoStoppedPlaying);

When the function videoStoppedPlaying is called within the video object, utilizing the keyword this directs it to the calling object, in this case, video.
Inside the video object, there are no properties named timeStarted or timePlayed, resulting in them being undefined. However, there is a property named duration, hence why you receive a value for duration.
For further insight into the properties within the video object, reference this documentation on HTML Audio/Video Properties.
Additionally, I have provided a live demo showcasing one more property.

Answer №2

To gather all the necessary data and assign it to your predefined properties, utilize the video "event."

Your function for when the video stops playing can take this form:

videoStoppedPlaying(event) {
    this.duration = event.target.duration;
    this.timePlayed = event.target.currentTime;
    console.log("Time Played: " + this.timePlayed);
    console.log("Duration: " + this.duration);
}

Remember to include "event" when invoking the function within the addEventListener:

this.video.addEventListener("pause", e => this.videoStoppedPlaying(e));

Answer №3

It is not recommended to utilize

addEventListener("pause", this.videoStoppedPlaying);
Rather, opt for the (pause) event within the HTML template.

For instance:

<video width="200" controls="true" poster="" id="video" (pause)="videoStoppedPlaying($event)">
    <source type="video/mp4" src="http://www.w3schools.com/html/mov_bbb.mp4">
</video>

The issue lies in failing to bind this. You could potentially implement:

this.video.addEventListener("pause", this.videoStoppedPlaying.bind(this));

Furthermore, it is advisable to utilize @ViewChild() instead of

document.getElementById("video")
.

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

What steps should I take to design and implement this basic search form?

Essentially, I have a three-page setup: - One page containing all possible search results such as: 'search result 1' 'search result 2' 'search result 3' - Another page with a search form and enter button. - And finally, a res ...

Angular 4: Prevent the HTML template of the parent component from being rendered in the

My component has the following routes: { path: ':id', component: ProjectDetailsComponent, children: [ {path: '', redirectTo: 'gathering', pathMatch: 'full'}, {path: ' ...

A guide on utilizing portals in Next.js to move a child element beyond its direct parent container

Current Setup Wrapper export const ContainerComponent = () => { return (<ChildComponent/>); } Child Component export const ChildComponent = () => { return ReactDOM.createPortal( <aside> <div>{"I am a c ...

Can a rotation animation be incorporated into an image in next.js when it is clicked?

Looking to enhance a next.js image with an animation? How about making it rotate 360 degrees upon each click? Despite my attempts at toggling classes, I can't seem to achieve the desired outcome. Any guidance would be greatly appreciated. Thank you in ...

Angular reactive forms allow you to create dynamic forms with fields that change

Consider the following data structure: formAviso: FormGroup; deapartamentos: [ {nombre: 'Amazonas', codigo: 41}, {nombre: 'Ancash', codigo: 43}, {nombre: 'Apurimac', codigo: 83}, ... ] constructor() { this.formAvi ...

I am experiencing an issue where my JSON array is only returning the last element. Any suggestions on how to

I am facing an issue with my JSON array and Ajax code. Here is the snippet of my code where I upload an Excel file, convert it to JSON, then save it as a string in my database: function exportExcelToTable() { $('#upload-excel-convert').chang ...

Using jQuery's each method to implement dynamic fallback with JSON data

Is it possible to set a fallback function dynamically from an AJAX JSONP call? I've been trying, but it doesn't seem to work. I'm not sure if I'm doing it right. Here's what I have: var GetFacebookData = function (data) { ...

The reCAPTCHA feature in Next.js form is returning an undefined window error, possibly due to an issue with

Trying to incorporate reCAPTCHA using react-hook-form along with react-hook-recaptcha is posing some challenges as an error related to 'window' being undefined keeps popping up: ReferenceError: window is not defined > 33 | const { recaptchaL ...

Find the value of a JavaScript string variable using an alternative name

My latest JavaScript function is designed to fetch JSON data from either a server or local files on any browser. This piece of code processes JSON from two sources: an XMLHttpRequest response, or a variable imported via script. In the case of the latter, ...

Enhance a React component by including additional properties when passing it into another component through props

I have a parent element with a dynamically changing height that I need to pass down to its child elements. To get and set the height of the parent element, I am utilizing a ref. The challenge lies in passing this height value from the parent component to ...

Monitoring variables in different AngularJS controllers

I have a component named histogram demo which includes a distinct controller with a variable known as $scope.selectedElements. I aim to monitor this variable in the primary appCtrl controller. How can I achieve access to this variable without using $rootSc ...

Updating items within a nested list in Redux can be achieved by carefully managing the state and implementing actions to add or remove

My current state is set up like this: Fruits: { 34: { FruitsID: 34, FruitsList:{apple, pineapple, banana} } } I want to update my fruit list by adding 'peach' and 'pear', while also removing 'apple&apos ...

The functionality of Angular 6 Material Nested Tree is disrupted when attempting to use dynamic data

In Angular 6, I am utilizing mat-tree along with mat-nested-tree-node. My objective is to dynamically load the data when the user toggles the expand icon. Attempting to apply the dynamic data concept from the Flat Tree example provided in Material Example ...

Why doesn't Mongoose automatically generate an _id for my array elements when I push them in?

I am looking for a way to have mongoose automatically add an _id field to the objects I push into my array. Here is my mongoose schema: var playerModel = new Schema({ user: { type: mongoose.Schema.Types.ObjectId, ref: "Users", }, cl ...

How can I display a new module in Angular without navigating to it?

After following the tutorial at https://angular.io/guide/lazy-loading-ngmodules#create-a-feature-module-with-routing I set out to create the following: My goal is to have a dedicated module for all customer-related components accessible through the /cust ...

Create a Typescript generic function that can return a variety of data types including strings, numbers, and

I have a function written in Typescript and I am looking to determine the return type based on the value retrieved from process.env. For instance, the variables in my Node process.env can be strings, numbers, or booleans. I want to fetch them with their s ...

What is the best method for extracting information from this data? (extracting data from

I need assistance. I've written multiple arrays to a text file and now I'm trying to parse them. What am I doing incorrectly? fs.readFile("./data.txt", "utf8", function(error,dataRes){ console.log('Reading data') ...

Is it possible to customize the width of text color alongside a progress bar?

My Bootstrap 4 Website contains the following HTML code snippet: <div class="container"> <div class="row"> <div class="col-md-6 mx-auto> <h2>Example heading text</h2> <h6>Example subh ...

What is the best way to display a Bootstrap alert above all other elements on the page?

I need help with adjusting the placement of my bootstrap alert. Currently, when the input box value is not valid and the button is clicked, the alert shows up below the input box. I would like it to appear in the middle of the page, on top of the text box. ...

Managing state in a live chat application

Currently seeking advice on managing state in a real-time messaging/chat app created with VueJS 2. The application is made up of multiple components as shown in the diagram below: Up to this point, I have successfully implemented the display of (fake) co ...