Building counter

Hi there,
Im buiding a counter app.
I got an issue with my algorithm scripting.
My intention is every time I click Reset button. It will reset the count back to 0, so when I click Decrease or Increase button it will decrease or increase 1 number at a time from 0.

However, with my code, when I reset, and then increase or decrease it will continue the number from the last count.

Can you help me out please?
See the link below :slight_smile:https://codepen.io/christiesunnie/pen/XWjXRRO

Looking at your reset button callback:

const reset = resetBtn.addEventListener('click', () => {
    valueNum.textContent = count - count; // you could just write 0 :-)
    valueNum.style.color = 'black';
});

There should be a third line where you reset your count variable to 0.

1 Like
valueNum.textContent = count - count;

While the above displays 0 when the Reset button is clicked, you have done nothing to change the actual value of count, so it retains the last value it had.

1 Like

Thank you! It works when I reinitialize count variable with 0. Thank you so much!

I have tried, the problem isn’t because I set :
valueNum.textContent = count - count or valueNum.textContent = 0 // they both work.
I don’t know if it might create bug later? with the first solution;

But what I need is the third line of reinitialization of count variable!

1 Like

You have quite a bit of repeated code. Whenever you see repeated code, put it in a function.

const valueNum = document.getElementById("value");
const decreaseBtn = document.getElementById("decrease");
const resetBtn = document.getElementById("reset");
const increaseBtn = document.getElementById("increase");

let count = 0;

const updateDisplay = () => {
  valueNum.textContent = count;
  let color = "green";
  if (count === 0) {
    color = "black";
  } else if (count < 0) {
    color = "red";
  }
  valueNum.style.color = color;
};

resetBtn.addEventListener("click", () => {
  count = 0;
  updateDisplay();
});

decreaseBtn.addEventListener("click", () => {
  count--;
  updateDisplay();
});

increaseBtn.addEventListener("click", () => {
  count++
  updateDisplay();
});

or to reduce even more repeated code:

const valueNum = document.getElementById("value");
const decreaseBtn = document.getElementById("decrease");
const resetBtn = document.getElementById("reset");
const increaseBtn = document.getElementById("increase");

let count = 0;

const changeColor = () => {
  let color = "green";
  if (count === 0) {
    color = "black";
  } else if (count < 0) {
    color = "red";
  }
  valueNum.style.color = color;
}
const updateCount = (val) => {
  count = val === 0 ? 0 : count + val;
  valueNum.textContent = count;
  changeColor();
};

resetBtn.addEventListener("click", updateCount.bind(null, 0));
decreaseBtn.addEventListener("click", updateCount.bind(null, -1));
increaseBtn.addEventListener("click", updateCount.bind(null, 1));
2 Likes

Lol well that escalated quickly…

.bind(...) is a very powerful tool, allowing you to attach the same function to different contexts, to pass in different parameters, or to use a function (as in this context) as an event listener with custom parameters, other then the Event object.

Not being critical, honest question, does bind(...) enter into the core js track?

It pops up in the React section.

1 Like

OK, last one I promise. What if you wanted to have more than one counter on the page? You could create a counter function and pass an id as an argument. This would allow you to create the counter HTML dynamically and allow each to operate independent of each other.

For example, your HTML could look like:

<main>
  <div id="counter1"></div>
  <div id="counter2"></div>
  <div id="counter3"></div>
</main>

and then your JavaScript could look like:

const counter = function (id) {

  const changeColor = () => {
    let color = "green";
    if (count === 0) {
      color = "black";
    } else if (count < 0) {
      color = "red";
    }
    domElems.valueNum.style.color = color;
  };

  const updateCount = (val) => {
    count = val === 0 ? 0 : count + val;
    domElems.valueNum.textContent = count;
    changeColor();
  };

  const createCounterDom = (id) => {
    document.getElementById(id).innerHTML = `
      <h1>Counter</h1>
      <h2 class="value"></h2>       
      <ul>  
        <li>
          <button class="btn decrease">decrease</button>
        </li>
        <li>
          <button class="btn reset">reset</button>
        </li>
        <li>
          <button class="btn increase">increase</button>
        </li>
      </ul>`;
  };

  const createDomElems = () => {
    createCounterDom(id);
    const valueNum = document.querySelector(`#${id} .value`);
    const decreaseBtn = document.querySelector(`#${id} .btn.decrease`);
    const resetBtn = document.querySelector(`#${id} .btn.reset`);
    const increaseBtn = document.querySelector(`#${id} .btn.increase`);

    resetBtn.addEventListener("click", updateCount.bind(null, 0));
    decreaseBtn.addEventListener("click", updateCount.bind(null, -1));
    increaseBtn.addEventListener("click", updateCount.bind(null, 1));
    
    return { valueNum };
  };
  
  const domElems = createDomElems();
  let count = 0;
  updateCount(0);
};

counter("counter1");
counter("counter2");
counter("counter3");
1 Like

Thanks you for your help! That is useful :slight_smile: