Salesforce Asked by Isha on January 20, 2021
I have a countdown in the setInterval function something like this :
count =5;
let myparam =this; //Have also tried passing this as some param but doesn't work according to the link below
this.Timer = setInterval(() => {
if(count<=0)
{
//refresh the screen
}
else
{
this.template.querySelector('classname').innerhtml=count;
}
count-=1
},1000)
but the countdown doesn’t decrease on the screen, the same works when I use bind(this), but I don’t want to use it due to the fact that bind(this) creates a copy of function and might cause memory leakage and impact performance. Also, when I use bind(this), the timer takes some time to appear on the same due to interval. Therefore I wanted to separate setInterval and function to be called inside the set interval so that the function can be called before setting the Interval as well and hence counter won’t take some time to display. Probably like
var timer=setInterval(updateTimer,1000);
where updateTimer is a arrow function but its doesn’t work as well.
Any help is appreciated!!
It's not clear that you defined Timer at the class level, this would create an error. Also, members should start with a lowercase character, while classes start with an uppercase character. This is more convention than a rule, but it's a good one to follow.
JavaScript is case-sensitive, so you must use innerHTML, not innerhtml.
Using bind(this)
is generally safe and doesn't leak any extra memory, assuming you clear the interval eventually.
You should be using automatic rerendering when possible; direct DOM manipulation is not recommended, but technically acceptable as long as you use lwc:dom="manual"
.
I wrote up an example using the recommended technique, as well as the not recommended technique you attempted.
import { LightningElement } from "lwc";
export default class Recommended extends LightningElement {
count = 5;
timer;
connectedCallback() {
this.timer = setInterval(() => {
if (!this.count) {
clearInterval(this.timer);
} else {
this.count--;
}
}, 1000);
}
disconnectedCallback() {
clearInterval(timer);
}
}
<!-- Recommended approach -->
<template>
<div>{count}</div>
</template>
import { LightningElement } from "lwc";
export default class NotRecommended extends LightningElement {
timer;
connectedCallback() {
let count = 5;
this.timer = setInterval(() => {
if (!count) {
clearInterval(this.timer);
} else {
count--;
this.template.querySelector("div").innerHTML = count;
}
}, 1000);
}
disconnectedCallback() {
clearInterval(this.timer);
}
}
<!-- Not Recommended approach -->
<template>
<div lwc:dom="manual"></div>
</template>
Correct answer by sfdcfox on January 20, 2021
I see a couple of things that needs correction in the current code, maybe because it is not the complete code.
this.count
.innerhtml
is not a valid property of the element. It should be innerHTML
.lwc:dom="manual
" attribute.Sample working example. (Not recomended approach)
import { LightningElement, api } from 'lwc';
export default class TodoApp extends LightningElement {
count = 10;
myTimer(){
let that = this;
return setInterval(function() {
if(that.count<=0){
// DO something
}
else{
that.template.querySelector('.timer').innerHTML= that.count;
}
that.count-=1
},1000, that)
}
connectedCallback(){
this.myTimer();
}
}
HTML
<template>
<div lwc:dom="manual" class='timer'>TIMER</div>
</template>
Recommended way
Use a property to show the count and manipulate it instead
timer = 0;
that.timer = that.count;
Answered by manjit5190 on January 20, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP