Powerful & Useful, Angular Countdown Timer w/ Minimal Code

Angular countdown timer showing days, hours, minutes, and seconds.

Last Updated on July 21, 2024 by E. Scott

I created this Angular countdown timer because it’s often difficult to find exactly what I need. Whether it’s an Angular or React component; something written in TypeScript or vanilla JavaScript. A specific service. Or an Axios GET request with error handling.

Whatever the case, I’m sure we’ve all been there. We need a feature and may find close variations, but not exact. Or a component that uses one technology while we’re interested in another. For me, I never rely on frameworks with components. Nor do I copy code from Stackblitz. I figure out how to build it just the way I want. This Angular countdown timer is a perfect example.

Git Repo

Regardless, I’m often amazed how much developers can accomplish in such few lines of code. No frameworks or libraries, just code in a native language. I think this is one of those times. Here’s a neat component—done so with minimal code.

  • Begin by setting the variables.
  • Basic date reference followed by the current time.
  • targetDate is of course the desired date to countdown from.
  • targetTime is the numeric version of the date.
  • difference is then subtracted by now (numerically).
  • The months array is used to illustrate the month name in the template. Feel free to substitute this w/ template literals.
  • We’re using basic ViewChild to retrieve the DOM elements, which are then populated w/ values. Some may argue Angular’s Renderer2 would be a better approach due to potential injection sinks. So this may change in a future version.
  • ngAfterViewInit is used because ViewChild elements do not become available at early life cycle hooks.
  • The isNaN bit is pertinent because days is not a number before it’s calculated. So unless you want NaN showing in the UI, use the ternary at the end of the ngAfterViewInit hook block.
  • In this hook, we call a repeating fn every 1 second. It updates the difference between then and now and divides it by an equation to make it readable/ presentable.
  • tickTock() creates a new date, and updates the aforementioned values. That’s it!

Angular Countdown Timer Typescript

If you’re familiar with TypeScript this Angular countdown timer shouldn’t be foreign to you. If it is though, feel free to leave a comment. Always happy to explain code. Regardless, understand the code. It’s not so much about the syntax but more-so about the concept. Building and applying conceptually makes us better developers. In turn, it becomes easier to learn new languages because we apply concepts. Then simply piece them together.

date: any;
now: any;
targetDate: any = new Date(2022, 12, 1);
targetTime: any = this.targetDate.getTime();
difference: number;
months: Array<string> = ["January", "February", "March", "April",
"May", "June", "July", "August", "September", "October", "November", "December"];

// Template literals is ideal for this scenario
currentTime: any = this.months[this.targetDate.getMonth()] +
' ' + this.targetDate.getDate() + ', ' + this.targetDate.getFullYear();

@ViewChild("days", { static: true }) days: ElementRef;
@ViewChild("hours", { static: true }) hours: ElementRef;
@ViewChild("minutes", { static: true }) minutes: ElementRef;
@ViewChild("seconds", { static: true }) seconds: ElementRef;

ngAfterViewInit() {
  setInterval(() => {
    this.tickTock();
    this.difference = this.targetTime - this.now;
    this.difference = this.difference / (1000 * 60 * 60 * 24);
    !isNaN(this.days.nativeElement.innerText)
      ? (this.days.nativeElement.innerText = Math.floor(this.difference))
      : (this.days.nativeElement.innerHTML = "<img src='https://i.gifer.com/VAyR.gif' />");
    }, 1000);
}

tickTock() {
  this.date = new Date();
  this.now = this.date.getTime();
  this.days.nativeElement.innerText = Math.floor(this.difference);
  this.hours.nativeElement.innerText = 23 - this.date.getHours();
  this.minutes.nativeElement.innerText = 60 - this.date.getMinutes();
  this.seconds.nativeElement.innerText = 60 - this.date.getSeconds();
}
<div class="count-down-timer">
  <p>Countdown to {{currentTime}}</p>
  <div class="wrapper">
    <div class="description">
      <p>Days</p>
      <p>Hours</p>
      <p>Minutes</p>
      <p>Seconds</p>
    </div>
    <div class="times">
      <p #days></p>
      <p #hours></p>
      <p #minutes></p>
      <p #seconds></p>
    </div>
  </div>
</div>
.count-down-timer {
  box-shadow: 2px 6px 9px 2px rgb(0 0 0 / 20%);
  text-align: center;
  background-color: black;
  color: white;
  border-radius: 6px;
  padding: 10px;
    > p { margin: 5px 0 15px 0; }

  .wrapper {
    .description, .times {
      display: grid;
      grid-template-columns: repeat(4, calc(25% - 8px));
      grid-column-gap: 10px;
    }

    .description {
      > p { font: normal 14px sans-serif; }
    }

    .times {
      p {
        letter-spacing: -5px;
        font: normal 50px courier, sans-serif;
      }
    }
  }
}

Without Angular

If you wanted to build this Angular countdown timer without thereof, the changes would be minimal. Nothing would change in the SCSS. How its integrated however will vary. Popular UI frameworks have similar concepts, but you’d need to work with a TS config file and either Vite or Webpack.

In JavaScript or TypeScript, you’d use getElementById or querySelector/ querySelectorAll instead of ViewChild. The four child p tags under class=”times”, would contain values that update via the setInterval.

Unless we’re building a web component we wouldn’t have access to life cycle hooks, so we’d need to make sure markup is loaded. Upon so, execute DOM events. This would replace ngAfterViewInit. This Angular component can also be converted to a technology of your choosing relatively easy.

As can this component that’s mainly TypeScript. I build things as often as I can in a variety of technologies so I’m always as confident as possible working. Such as this UI Bar Chart.

Conclusion

Hope you enjoyed this post. Regardless, I’d be very grateful if you left a comment below telling me what you did or didn’t like. If you get stuck, see the Stackblitz link here. Otherwise, feel free to use this wherever you’d like. Advertisements, a test, games, etc. Additionally, if you think this Angular countdown timer can be improved, let me know!

2 Comments

Leave a Reply

Your email address will not be published.


*