Andrey Jakovenko Andrey Jakovenko - 4 months ago 35
TypeScript Question

Cleared countdown timer when you restart the page

I made a countdown timer on the typescript

now we need to make so that the timer is not reset after a reboot, store in localStorage.

like all true logically made, but still throws

code below:

PasteBin link

LS Class

export class LS {
public set (key: string, data: any) {
let result = (data.constructor == Object) ? JSON.stringify(data) : data;
localStorage.setItem(key, result);
}

public get (key: string) : any {
let jsonObject = null;
let data = localStorage.getItem(key);

try {
jsonObject = JSON.parse(data);
}
catch(e) {
jsonObject = data;
}

return jsonObject;
}

public rm(key:string) {
localStorage.removeItem(key);
}
}


CountdownService class

export class CountdownService {
protected timeData: Object = {
days: 0,
hours: 0,
minutes: 0,
seconds: 0
};

public ONE_SECONDS = 1000;

protected callback:Function;
protected ls:LS;
protected nameTimeData:string = 'timingData';

constructor() {
this.ls = new LS();
}

public start(hours: number, minutes:number, _callback:Function) {
this.callback = _callback;
let milliseconds = this.toMilliseconds(hours, minutes);
let deadline = new Date(Date.parse(new Date().toString()) + milliseconds);

this.initializeClock(deadline);
}

public getTimeData():Object {
return this.timeData
}

protected toMilliseconds(hours, minutes) {
let secondsHours = hours * 3600;
let secondsMinutes = minutes * 60;
return (secondsHours + secondsMinutes) * this.ONE_SECONDS;
}

protected getTimeRemaining(endTime) {

let currentTime = new Date().toString();
/*let lsTime;

// This block does not work correctly
if (this.ls.get(this.nameTimeData) != null) {
lsTime = this.ls.get(this.nameTimeData);
console.log(lsTime);
this.ls.set(this.nameTimeData, new Date().toString());
} else {
this.ls.set(this.nameTimeData, new Date().toString());
lsTime = this.ls.get(this.nameTimeData);
}
*/
let t = Date.parse(endTime) - Date.parse( currentTime );
let seconds = Math.floor((t / this.ONE_SECONDS) % 60);
let minutes = Math.floor((t / this.ONE_SECONDS / 60) % 60);
let hours = Math.floor((t / (this.ONE_SECONDS * 60 * 60)) % 24);
let days = Math.floor(t / (this.ONE_SECONDS * 60 * 60 * 24));

return {
'total': t,
'days': days,
'hours': hours,
'minutes': minutes,
'seconds': seconds
};
}

protected initializeClock(endTime) {

let updateClock = () => {
let t = this.getTimeRemaining(endTime);

this.timeData['days'] = t['days'];
this.timeData['hours'] = ('0' + t.hours).slice(-2);
this.timeData['minutes'] = ('0' + t.minutes).slice(-2);
this.timeData['seconds'] = ('0' + t.seconds).slice(-2);

if (t.total <= 0) {
clearInterval(timeInterval);
this.callback();
}
};

updateClock();
var timeInterval = setInterval(updateClock, this.ONE_SECONDS);
}
}


Calling code

let timeData = this.test['time'].split(':');
console.log(timeData); // ["1", "1"]
this.cds.start(timeData[0], timeData[1], this.endTestCallback);

Answer

It looks like the calling code sets the end time relative to the current time.. Each time you refresh the page, it recalculates a new end time and the counter appears to reset.

You need to adjust your logic - I suggest storing the end time instead. This can be done outside your CountdownService class.

Adjust the CountdownService.start() method to take a Date object (which represents an absolute point in time, instead of a relative offset from current time).

public start(deadline: Date, _callback:Function) {
    this.callback = _callback;
    this.initializeClock(deadline);
}

In the code where you use the CountdownService, use your LS service to save the end date if it hasn't been set already. Something like this:

let storage = new LS();
let deadline = storage.get('deadline');

if (!deadline) { // set end time if not set already
    let timeData = this.test['time'].split(':'); 

    console.log(timeData); // ["1", "1"]
    // `+new Date` is a trick for converting a date to milliseconds
    deadline = new Date(+new Date() + (timeData[0] * 3600 + timeData[1] * 60) * 1000);
}


this.cds.start(deadline, this.endTestCallback); 
Comments