Stopwatch Exercise Issue - JS Mastery Part 2

Hi team,

I am currently trying to complete the stopwatch exercise at the end of the Objects section.

I am running into problems with my implementation, namely that when I try to call the stopwatch.duration variable, it gives NaN. When I check the typeof of stopwatch.start() and stopwatch.stop() it presents a number - I can’t see why I am not allowed to use these number primitives in their normal way. I have a feeling that the JS engine thinks I am trying to subtract a function from a function?

Please help.

Here is my implementation;

const stopwatch = {
start: function getTime() {
let now = new Date();
let time = 1 * (now.getMinutes() + “.” + now.getSeconds()); //converts time from string to number
return time;
},
stop: function stopTime() {
let then = new Date();
let time = 1 * (then.getMinutes() + ‘.’ + then.getSeconds()); //converts time from string to number
return time;
},
reset: function resetTime() {
this.start = 0;
this.stop = 0;
console.log(“Timer is reset”);
},
duration: this.stop() - this.start()
};

SOLUTION

Although it isn’t flawless, I realised that I needed to define a variable within the object first, call it duration, and add/subtract the start/end times via use of this variable. Here’s the modified implementation, with some other tweaks;

const sw = {
result: 0,
duration: function timeResult() {
if (this.result === 0) console.log(The timer hasn't started);
if (this.result !== 0)
console.log(
The time elapsed since start is ${this.result.toFixed(2) * 100} seconds
);
},
start: function getTime() {
let now = new Date();
let time = 1 * (now.getMinutes() + “.” + now.getSeconds());
this.result -= time;
return “Stopwatch started”;
},
stop: function stopTime() {
let then = new Date();
let timed = 1 * (then.getMinutes() + “.” + then.getSeconds());
this.result += timed;
return “Stopwatch stopped”;
},
reset: function resetTime() {
this.result = 0;
console.log(“Timer is reset”);
}
};

Any comments or feedback would be much appreciated.

Happy coding!

Just progressed with this a bit and attempted to move the functions into the prototype of the constructor. But when I try and call the result variable via Sw.result, I get NaN or undefined. As a consequence, the entire stopwatch doesn’t work. The functions are successfully placed in the prototype, however I can’t figure out why the result variable is inaccessible… Please help!

function Sw() {
result = 0;
Object.defineProperty(this, “result”, {
get: function() {
return result;
},
set: function(value) {
result = value;
}
});
}

Sw.prototype.start = function() {
let now = new Date();
let time = 1 * (now.getMinutes() + “.” + now.getSeconds());
this.result -= time;
return “Stopwatch started”;
};
Sw.prototype.stop = function() {
let then = new Date();
let timed = 1 * (then.getMinutes() + “.” + then.getSeconds());
this.result += timed;
return “Stopwatch stopped”;
};
Sw.prototype.reset = function() {
this.result = 0;
console.log(“Timer is reset”);
};
Sw.prototype.duration = function() {
if (this.result === 0) console.log(The timer hasn't started);
if (this.result !== 0)
console.log(
The time elapsed since start is ${this.result.toFixed(2) * 100} seconds
);
};

I ran your code, and result seemed accessible to me. For example if I add this after your code…

const sw = new Sw();
console.log('result:', sw.result);

I get result: 0

1 Like

It seems like toFixed() is a better solution, but it is not! In some cases it will NOT round correctly. Also, Math.round() will NOT round correctly in some cases.

To correct the rounding problem with the previous Math.round() and toFixed(), you can define a custom JavaScript rounding function that performs a “nearly equal” test to determine whether a fractional value is sufficiently close to a midpoint value to be subject to midpoint rounding. The following function return the value of the given number rounded to the nearest integer accurately.

Number.prototype.roundTo = function(decimal) {
  return +(Math.round(this + "e+" + decimal)  + "e-" + decimal);
}

var num = 9.7654;
console.log( num.roundTo(2)); //output 9.77