LWC property is not reactive

Classic... Javascript is quite weird, this changes quite frequently with respect to the context.

in setInterval , this does not refer to your binded variables, but something else.

You have to pass this as some param in setInterval

import { LightningElement, api, track, wire } from 'lwc';

export default class LoadContact extends LightningElement {

    @track closedt ='2019-08-09';
    @track daysFinal =0;
    @track hoursFinal;
    @track minutesFinal;
    @track secondsFinal;
    timeIntervalInstance;
    totalMilliseconds = 0;


    datecounter(){       

        let oppCloseDt = new Date(this.closedt);       
        let months = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];                 
        let monthName = months[oppCloseDt.getMonth()];                  
        let dateNumber = oppCloseDt.getDate();                  
        let yearNumber =  oppCloseDt.getFullYear();                 
        let closeDateVar = monthName+' '+dateNumber+' '+yearNumber;                  
        let opptCloseDate = new Date( closeDateVar+" 00:00:00 ");
        let myparam = this;

        // eslint-disable-next-line @lwc/lwc/no-async-operation
        setInterval(function() {
            let opptyCloseDate = new Date(  closeDateVar+" 00:00:00 "); 
            window.console.log('opptyCloseDate...' + opptyCloseDate);                
            let nowdate = new Date();                   
            let timeDiff = opptyCloseDate.getTime()- nowdate.getTime();  
            let seconds=Math.floor(timeDiff/1000); // seconds                   
            let minutes=Math.floor(seconds/60); //minute                    
            let hours=Math.floor(minutes/60); //hours                   
            let days=Math.floor(hours/24); //days                   
             hours %=24;                    
             minutes %=60;                  
             seconds %=60;   

             myparam.hoursFinal =hours;
             myparam.daysFinal =days;
             myparam.minutesFinal =minutes;
             myparam.secondsFinal =seconds;
             myparam.daysFinal =null;
             myparam.daysFinal = days;
             window.console.log('this.hoursFinal...' + myparam.hoursFinal);
             window.console.log('this.daysFinal...' + myparam.daysFinal);



        }, 5000 , myparam);
    }


}

Playground Link : https://developer.salesforce.com/docs/component-library/tools/playground/6dm391HNp/2/edit

Src: https://stackoverflow.com/questions/7890685/referencing-this-inside-setinterval-settimeout-within-object-prototype-methods/7890978

JS


This pitfall is quite common for salesforce developers working on Javascript. Set-Interval actually changes the context of this to window as functions like setInterval, setTimeout etc are async functions and hence these functions run after the main thread has finished processing. This can be addressed by any of 2 options:

  1. Lexical Scoping - old fashioned (pls do a google search for understanding)
  2. Arrow functions - Modern javascript. (PFB)

Just change the callback function from:

setInterval(function(){}, 500);

To

setInterval(() => {}, 500);

For simple understanding, Arrow functions don't have their own scope because of which it takes the scope of parent object.

There are many other advantages of arrow functions. Further read: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions