stonefish
stonefish

Reputation: 125

How to preserve the leading zero when changing a string into a number using Javascript?

How do I convert a string such as "03" into a number and keep the zero at the beginning of the string? Using Number("03") will remove the leading 0 and return 3, but I want to keep the 0 there. How would I go about doing this?

Here's my JS function for context:

function format(input, unit) {
  if (new RegExp(unit, 'i').test('minute second')) {
    if (String(input).length === 1) return Number(`0${input}`);
    else return input;
  }
  else if (unit === 'hour') {
    return input;
  }
}

Thanks!

EDIT: What I got so far

let timer = {
  hours: 0,
  minutes: 1,
  seconds: 30,
  updateTimerDisplay() {
    document.getElementById('hour').innerHTML = this.hour;
    document.getElementById('minute').innerHTML = String(format(this.minutes, 'minute'));
    document.getElementById('second').innerHTML = String(format(this.seconds, 'second'));
  },
  startTimer() {
    const { updateTimerDisplay: updateDisplay } = this;
    let update = setInterval(_ => {
      this.seconds -= 1;
      if (this.seconds < 0) {
        this.seconds = 59;
        this.minutes -= 1;
      }
      if (this.minutes < 0) {
        this.minutes = 59;
        this.hours -= 1;
      }
      updateDisplay();
    }, 1000);
  }
};
timer.updateTimerDisplay();
timer.startTimer();

function format(input, unit) {
  if (new RegExp(unit, 'i').test('minute second')) {
    if (String(input).length === 1) return `0${input}`;
    else return String(input);
  }
}

Upvotes: 0

Views: 171

Answers (1)

trincot
trincot

Reputation: 350137

Some issues:

  • Spelling of this.hour: should be this.hours
  • By calling updateDisplay you don't pass on the expected value for this. It is better to just keep the original name of the method, and use this.updateTimerDisplay.
  • Don't convert the 0-prefixed string back to number: you are interested in something to display, so keep the string format.

Without changing too much else in your code, the above corrections make it work:

let timer = {
  hours: 0,
  minutes: 1,
  seconds: 30,
  updateTimerDisplay() {
    // Use textContent, not innerHTML (that is for HTML content)
    document.getElementById('hour').textContent = this.hours; // spelling!
    // The function format returns a string, so no need to call String on it:
    document.getElementById('minute').textContent = format(this.minutes, 'minute');
    document.getElementById('second').textContent = format(this.seconds, 'second');
  },
  startTimer() {
    // Don't read a function reference into a variable, as you'll lose the this-binding
    // --------- const { updateTimerDisplay: updateDisplay } = this;
    let update = setInterval(_ => {
      this.seconds -= 1;
      if (this.seconds < 0) {
        this.seconds = 59;
        this.minutes -= 1;
      }
      if (this.minutes < 0) {
        this.minutes = 59;
        this.hours -= 1;
      }
      // By having `this.` here, you pass that this-reference to the function
      this.updateTimerDisplay();
    }, 1000);
  }
};
timer.updateTimerDisplay();
timer.startTimer();

function format(input, unit) {
  // RegExp is overkill here. Just use includes:
  if (['minute', 'second'].includes(unit.toLowerCase())) {
    // Don't convert with Number: it must be a string:
    if (String(input).length === 1) return `0${input}`;
    else return String(input);
  }
}
<span id="hour"></span>:<span id="minute"></span>:<span id="second"></span>

Upvotes: 1

Related Questions