There are a couple of issues here: specifically, the `this.myMethod` function is not recognized as a function, and the click event added by the `addEventListener` function

I am currently attempting to create a timer using vue.js, but I am encountering some issues with my methods section:

methods: {         
    saveRunningMethod() {
        var runningData = {
            duration: `${this.hour} : ${this.minute} : ${this.second}`,
            username: this.$store.state.user.username
        }
        this.$store.dispatch('saveRunning' , runningData)
        console.log(runningData);
    },
    startTimer(){     
        this.isTimerStart = true;
        var timer = window.setInterval(() => {

           var e = document.getElementById("stopBtn")
           e.addEventListener("click", function(){ 
               clearInterval(timer) 
               this.isTimerStart = false;
               console.log("lets Save it")
               this.saveRunningMethod()
               });

           if(this.mSecond < 9)
                this.mSecond +=1
            else
                this.mSecond=0

           if(this.mSecond==9)
                this.second +=1                

            if(this.second>59)                   
                this.second=0

            if(this.second==59)
                this.minute +=1

            if(this.minute>59)
                this.minute=0

            if(this.minute==59)
                this.hour+=1             

    },100);

    }
}

In the code above,

e.addEventListener("click", function(){
is used to stop the timer when clicking on the 'stop' button. However, this method seems to be running multiple times and resulting in multiple executions of console.log as depicted in this image:

Another issue I am facing is with the line: this.saveRunningMethod(). When I try to call this method within my startTimer() method, I receive an error stating "this.saveRunningMethod() is not a function."

Finally, for the timer setup utilizing setInterval, if you have any suggestions for a more efficient solution, your input would be greatly appreciated.

UPDATE: Including my HTML component below:

<div class="row p-2 m-3 mt-3">
        <div class="col-12 p-0 animated fadeInUp mt-3">
            <p class="text-center">Your last record was : 00:00:00</p>
        </div>
        <div class="col-12 p-0 animated fadeInUp mt-3">
            <h1 class="text-center timer">
                {{this.hour}}:{{this.minute}}:{{second}}:{{mSecond}}
            </h1>
        </div>
    </div>
    <div class="row p-2 mt-3" v-bind:class="[this.isTimerStart==false ? 'show' : 'hide']">
        <div class="col-12 p-0 animated tada text-center">
            <button class="btn-link timerImg" @click="startTimer()">
                <img class="img-fluid timerImg" src="../../static/timerStart.png" />
                <p>Start</p>
            </button>
        </div>
    </div>

    <div class="row p-2 mt-3" v-bind:class="[this.isTimerStart ? 'show' : 'hide']">
        <div class="col-12 p-0 animated tada text-center">
            <button id="stopBtn" class="btn-link timerImg">
                <img class="img-fluid timerImg" src="../../static/timerStop.png" />
                <p>Stop</p>
            </button>
        </div>
    </div> 

Thank you for your assistance.

Answer №1

As per the information from a reliable source, the functionality of window.setInterval() is as follows:

It repeatedly calls a specified function with a fixed time delay between each call.

When the method startTimer() is triggered, it attaches a click event listener to the stop button every 100 milliseconds. Thus, if there is a 3.3-second delay before clicking the stop button after page load, the click event will have been added to the button 33 times:

var timer = window.setInterval(() => {

    var e = document.getElementById("stopBtn")
    e.addEventListener("click", function() {
        // This code will run 33 times on stop button click.
    })
    ...
}, 100)

If there is a 5.4-second delay prior to clicking the stop button after loading the page, the click event will have been attached to the button 54 times!

Rather than utilizing window.setInterval(), it is recommended to use window.setTimeout(). As stated by this resource, this is its purpose:

It executes a code snippet or a function after a specified delay.

In essence, window.setTimeout() sets up a timer that runs only once after a user-specified delay.

Regarding the error mentioning "

this.saveRunningMethod() is not a function
," the issue arises due to context changes within the callback function passed to addEventListener(). The value of this switches to the button itself rather than your object. To circumvent this problem, an arrow function can be passed to addEventListener(), maintaining the context unchanged (thus keeping this as your object inside the arrow function):

window.setTimeout(() => {
    var e = document.getElementById("stopBtn")
    e.addEventListener("click", () => {
        this.isTimerStart = false;
        console.log("Saving now");
        this.saveRunningMethod();
    });
}, 100)

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

Is it possible to display two menus on opposite sides of the screen while using Google Maps?

Currently, I am working on developing a Progressive Web App using Vue.js and Vuetify.js. My goal is to have two buttons overlaid on Google Maps - one on the left side of the screen to open a navigation drawer, and another on the right side to display user ...

evt.target consistently returns the initial input within the list of inputs

My React file uploader allows users to attach multiple file attachments. Each time a user clicks on an input, I retrieve the data-index to identify the input position. renderFileUploader() { let file_attachment = this.state.file_attachment.map(fun ...

Transmitting a jQuery array from the client to the server using AJAX in

I've looked at so many posts about this issue, but I still can't get my code to work. My goal is to retrieve a PHP array of values from the checkboxes that are checked. Here is my code snippet: <!doctype html> <html> <head> & ...

Transforming the response.render method in Express to be a promise-enabled

I have a task at hand where I need to develop a render method that constructs HTML blocks into a string. Initially, it appears to be working fine, but I ended up using the infamous "new Promise" and now I'm not sure if my approach is correct. Here&apo ...

What is the best way to handle JSON data errors when a value is undefined?

I am currently working on a piece of code that displays JSON data in HTML. However, if a value is undefined, it doesn't display anything. How can I handle this error so that if a value is undefined, it will show "N/A" instead of breaking the code? ...

Changing a class using JavaScript: Adding and removing class dynamics

Currently, I am attempting to create a function that will toggle the visibility of a visual object on and off whenever the user clicks on it. Additionally, I need to implement a click event listener within the HTML class named btn-sauce. Unfortunately, my ...

Enable Row Editing with a Click in Material Table

Utilizing the material-table library, I am implementing a feature to enable table rows to be editable upon double-click. The goal is for clicking on a row to trigger the same action as clicking the edit button located in the actions column on the leftmost ...

The NodeJS module 'request' is producing symbols instead of expected HTML content

Currently, I am delving into the world of Nodejs and experimenting with web scraping using node.js. My tools of choice are the node modules request and cheerio. However, when I attempt to request a URL, instead of receiving the HTML body, I get strange s ...

Tips for using multiple Angular directive modules in PprodWant to enhance your Pprod experience by

Currently, I am working on jhipster Release 0.7.0 and our jhipster app has multiple types of directive modules – one for the index page and another for common directives. However, when we run the app on Prod profile, an exception occurs: [31mPhantomJ ...

Set the display property of all child elements within the DIV to none

CSS <div class="container"> <span></span> <input type="text"> </div> JavaScript function hideElements(){ let container = document.querySelector(".container"); let elements = ...

Utilizing Asynchronous Functions within a Loop

I have a situation where I am working with an array and need to make API calls for each index of the array. Once the API call is resolved, I need to append the result in that specific element. My goal is to ultimately return the updated array once this pro ...

"Enscroll – revolutionizing the way we scroll in

I recently incorporated the "enscroll" javascript scroll bar into my webpage. You can find more information about it at <div id="enscroll_name"> <ul> <li id="p1">product1</li> <li id="p2">product2</li> ...

Understanding the source of an useEffect's trigger to create a conditional statement

Within my useEffect, I have two states included in the dependencies array: const [currentTab, setCurrentTab] = useState('open'); const [searchParams, setSearchParams] = useState(''); useEffect(() => { if (condition) { // logi ...

The JavaScript in the Laravel file isn't functioning properly, but it works perfectly when incorporated via CDN

Successfully implemented code: <script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.0.2/anime.min.js"></script> <script type="text/javascript"> var textWrapper = document.querySelector('.ml6 .letters'); textWrapper.in ...

Utilize Express.js to seamlessly stream and process uploaded files with formidable and gm, ensuring a streamlined process without

I am looking for a solution to upload and resize an image in one step without having to write to disk twice. For uploading images, I am using: node-formidable: https://github.com/felixge/node-formidable And for resizing the images, I am using: gm: Howev ...

Determine which children should be displayed in a Kendo treeview based on the field titled "ParentId"

After converting a list of records into JSON format, I am looking to transform this data into a hierarchical KendoTreeView. Here is the JSON data: [ { "id": 1, "name": "A", "parentID": 0, "hasItems": "true" }, { "id": 2, "name": "B", "parentID": 1, "has ...

Resolving the Enigma: Querying jQuery for Real-Time Validation and

I'm fairly new to jQuery and I'm facing a challenge in my registration form script. Specifically, I want to check if the entered username or email is already taken while the user is typing. Currently, this functionality works by making a json req ...

Transform Vue.js into static HTML output

Is there a way to convert a Vue.js component into static html without the need for javascript? I am specifically interested in retaining styles. I am searching for a library where I can execute code similar to this: SomeNestedComponent.vue <template> ...

Unable to locate the root element for mounting the component in Cypress with React

I am currently testing my react app, which was created using create-react-app, with the help of cypress. Unfortunately, I encountered an error that looks like this: https://i.stack.imgur.com/xlwbo.png The error seems to be related to trying to fetch an ...

Signal for a complete 360 degree rotation of an image

Looking to enhance my 360 image rotator with an indicator that fades out after the first image. I added this function to the end of my 360.js: (function(){ if( $('#first').css('visibility','hidden')) { $('#rotat ...