0

Below is the code for timer which is not working as expected

HTML code:

<template>     
<lightning-card title="Styling using dynamic CSS">
        <div class="dynamicDiv sldx-box slds-box slds-box_small">
            <p class="dynamicP" style={getStyle}>
                {percentage}
            </p>
        </div>
        <lightning-button label="Start timer" onclick={handleStartTimer}></lightning-button>
        <lightning-button label="Reset timer" onclick={handleResetTimer}></lightning-button>
    </lightning-card>
</template>

JS File:

import { LightningElement } from 'lwc';

export default class LwcStyling extends LightningElement {
    percentage = 0;

    handleStartTimer(event){
        setInterval(myTimer, 1000);
        function myTimer(){
            this.percentage += 1;
            console.log(`hi ${this.percentage}`);
        }
    }
    //this will reset the timer
    resetPercentageChange(event){
        this.percentage = 0;
    }
    get getStyle(){
        return `width: ${this.percentage}% ; background-color: green`;
    }
}

Here I was expecting as the timer increments it will increment the percentage value as well but when I tried to console the percentage in the same method NAN was printed in the console.

1 Answer 1

3

When you declare a function via function keyword it will have its own this. Docs:

Until arrow functions, every new function defined its own this value (a new object in the case of a constructor, undefined in strict mode function calls, the base object if the function is called as an "object method", etc.)

Therefore inside myTimer the value of this.percentage is undefined so adding 1 to it will result in NaN.

Just using an arrow function will fix it since they inherit this:

handleStartTimer(event){
    setInterval(() => {
        this.percentage += 1;
        console.log(`hi ${this.percentage}`);
    }, 1000);
}

Another way to fix this issue is binding the value of this via bind() method:

handleStartTimer(event){
    setInterval(myTimer, 1000);
    function myTimer(){
        this.percentage += 1;
        console.log(`hi ${this.percentage}`);
    }.bind(this);
}
1
  • Had a feeling that this was due to Javascript's odd handling of this, but wasn't quite sure. Commented Oct 17, 2024 at 18:46

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.