Angular doesn't update class field when event listener is triggered by button

My Objective:

  • To generate a random number

  • To start a timer that counts to this number and then displays a button with a random margin

  • To stop the first timer and start another when the button is clicked

  • To calculate the time elapsed between the appearance of the button and its click

I attempted to create a boolean field in a component class, so that when the button is clicked, the boolean changes to true. Then, the timer checks this boolean value at each tick, deleting the button and restarting the initial timer if it's true.

The issue arises when the button is clicked because the 'clicked' field doesn't change as expected. What am I missing here?

import { Component, OnInit } from '@angular/core';
import {TimerObservable} from "rxjs/observable/TimerObservable";


@Component({
  selector: 'app-gra',
  templateUrl: './gra.component.html',
  styleUrls: ['./gra.component.css']
})
export class GraComponent implements OnInit {

  randNum: any;
  timerSub: any;
  userTimerSub: any;
  clicked: boolean;


  constructor() { }

  ngOnInit() {
    this.randNum = 3+ Math.floor(Math.random()*3);
    console.log('random: ' + this.randNum)
    this.clicked = false;
    let timer = TimerObservable.create(0, 1000);
    this.timerSub = timer.subscribe( d => this.timerFunction(d) );
  }

  timerFunction(d){
    console.log(d);

    if(d === this.randNum){

      var btn = document.createElement("BUTTON");        // Create a <button> element
      var t = document.createTextNode("CLICK ME");       // Create a text node

      btn.appendChild(t);
      btn.id = "button"

      let margin  = Math.floor(Math.random()*500);

      document.body.appendChild(btn);                    // Append <button> to <body>
      btn.setAttribute('style', 'margin-top: ' + margin + "px;");
      document.getElementById("button").addEventListener("click", this.buttonClick.bind(this));

      this.timerSub.unsubscribe();

      let timer = TimerObservable.create(0, 1000);
      this.userTimerSub = timer.subscribe( d => this.userTimerFunction(d) );
      this.randNum = 3 + Math.floor(Math.random()*3);
      console.log('new rand: ' + this.randNum)
    }
  }

  userTimerFunction(d){
    console.log('user' + d)
    console.log(this.clicked)
    if(this.clicked == true){
      console.log('It took you ' + d + 'seconds');

      this.userTimerSub.unsubscribe();
      var element = document. getElementById("button");
      element.parentNode.removeChild(element);

      let timer = TimerObservable.create(0, 1000);
      this.timerSub = timer.subscribe( d => this.timerFunction(d) );
    }
  }

  buttonClick(){
    console.log('clicked: ' + this.clicked);
    this.clicked = true;
  }
}

Answer №1

It is my belief that by binding the click method in this manner, the 'this' keyword may not be bound as expected and the 'clicked' property might not change accordingly. You could explore using the fat arrow syntax for binding the 'this' keyword.

addEventListener("click", () => this.buttonClick())

Alternatively, I suggest utilizing Angular's built-in renderer service for handling dom manipulations if you are working within an Angular environment.

this.renderer.listen(elementRef.nativeElement, 'click', (evt) => {
    console.log('Clicking the document', evt);
})

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 is the best way to save data from a jQuery plugin to a database using ASP .NET MVC?

I have a jQuery plugin called "Slider" that displays the current price of an item. I would like to enhance it by allowing users to change prices using the jQuery slider and update them in the database. Here is the model: public class Item { public in ...

Is there a way to prevent the use of any keys other than letters and numbers in the search input field of a datatable, such as function keys or shortcut keys?

jQuery Query: Is it possible to trigger the search function only when alphabet and number keys are typed? For DataTables, global searching should only start when at least 3 characters have been entered. $(document).on('draw.dt','.dataTable ...

Unique JQuery CSS dynamic corner scenario

I am faced with a situation where I am dynamically adding a CSS class to a div that contains a flash message using the following line of code: $("div#flash_notice").toggleClass('success'); The JavaScript code is located in the micropost view, ...

Hide or eliminate SVG element

Can CSS or jQuery be used to remove or hide an SVG element? I am familiar with modifying div elements using CSS. For example: div[style="position: absolute; cursor: pointer; width: 207px; height: 95px; left: 513px; top: 0px; -webkit-transform-origin: ...

Error: Unable to access the 'headers' property since it is null. MEAN stack issue

I'm in the process of developing a basic ToDoApp using the MEAN (Angular 2) stack, but I'm encountering an issue with the http.post request. Whenever I execute the post method, the current JSON object successfully gets added to the database. Howe ...

Activate when every single pixel within an element is see-through

I've designed a web page that includes two canvas elements stacked on top of each other. The purpose of this setup is to allow me to "erase" the top canvas and reveal an image loaded into the bottom canvas. So far, this functionality has been working ...

Executing a function with AXIOS within a v-for loop in Vuejs

After going through numerous articles, posts, and inquiries on various platforms including StackOverflow, I still couldn't find the solution to my problem. My task is to create a simple comment and reply feature for my Laravel project. * Here is an o ...

Leveraging WebWorker in Azure DevOps WebExtension

I am attempting to employ a WebWorker within a WebExtension on an Azure DevOps Server. Data processing for a large repository can be quite resource-intensive, prompting me to utilize a WebWorker for background calculations. However, when I try to instant ...

Struggling with conditionally rendering components or elements in React while managing state

I am currently working on a react login/signup form where the user lands on the signup section by default. My goal is to display the login section when the user clicks on the login button and show the products section when the user clicks on "Get Started" ...

Show pictures in Angular 10 after uploading them via Multer on the Node.js server

My web application is built using the MEAN stack. I am utilizing Multer to save images in an artImages folder on my Node.js server. The post request uploads images and stores their paths along with other data in MongoDB. const storage = multer.diskStorage( ...

Content briefly appears and then vanishes with the use of ng-if

On my webpage, I have content that is enclosed in an ng-if directive as shown below: <div ng-if="ShowMessgae" class="text-danger"> <p> <strong> Message displayed to User </strong> </p> < ...

Angular 6: Retrieving an array of objects from JSON using the httpClient in Angular

My goal is to populate a table with data retrieved from my backend API. The table requires an input called rows, which should be an array of objects. Each object represents a row in the table and contains key-value pairs for column names and values. The ba ...

Issue: The module "node:util" could not be located while attempting to utilize the "sharp" tool

Upon adding sharp to my Node.js application and attempting to use it, I encountered the following error: /Users/username/Documents/GitHub/Synto-BE/node_modules/sharp/lib/constructor.js:1 Error: Cannot find module 'node:util' Require stack: - /Use ...

Tips for hiding a popover in Angular when clicking outside of it

In a demo I created, rows are dynamically added when the user presses an "Add" button and fills in a name in an input field. Upon clicking "OK," a row is generated with a Star icon that should display a popover when clicked. While I have successfully imple ...

Using Angular 5 custom validations in combination with Bootstrap 4 validation pseudo-classes (:valid, :invalid)

Bootstrap 4 validation styles are based on the classes form-control:valid and form-control:invalid. Angular provides the option to apply any custom class when a field is in error. If I adhere to the specifications outlined here: https://getbootstrap.com/d ...

Explore an associative array in a circular list format

I have a unique requirement to traverse through an associative array like a circular list. The associative array is structured as follows: array = {item1:array(...), item2:array(...), ...} When I reach the end of one array, I want it to seamlessly transi ...

Ways to mandate a field to only be of type object in TypeScript

I need to design a type that includes one mandatory property and allows for any additional properties. For instance, I require all objects to have an _id property of type string. {_id: "123"} // This will meet the criteria {a: 1} // This will not work as i ...

What is the best way to test an external Data Transfer Object (DTO

I am looking to test an external Data Transfer Object (DTO) that undergoes frequent changes. For example: Here is a sample JavaScript (JSON) file below: // JavaScript const type User = { id: Number, name: String } // JSON user: { id: Number, ...

Scrolling through image galleries with automatic thumbnails

I am looking to create an automatic image scrolling feature on my webpage using a bunch of images I have. I have searched for a solution but have not found one that fits my requirements. I don't think a carousel is the right approach for this. The sol ...

Is the state of the React.js component empty?

HTML: <!-- index.html --> <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>React Tutorial</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.6/react.js"></script> ...