Pomodoro Clock: 26ish tests passing

Hi friends,

I’d love a second pair of eyes on my Pomodoro Clock. It’s built using vanilla JS, and I commented throughout the code so it should be easy to read. :crossed_fingers:

I don’t understand why it is failing some of the simple tests (like the function of the break-decrement button) and why it says my countdown is not reaching zero.

The number of tests passing varies. It went to 23/29, and when I let the tests keep running, it got all the way up to 26, before dropping back down to 16.

As far as I can tell the app works as it should, so I’m not really sure what needs to be restructured to appease the test environment.

Any advice would be greatly appreciated!

1 Like

Hey there!

So for me, I only got a score of 16/29

I’ve got a few things that I’ll break up into sections for ya:

  1. Project setup on Codepen

    • In the HTML, you bring in a script tag for freeCodeCamp’s project test as well as the link tag for the google font API. Rather than putting them in the HTML, both of these can be hoisted into the settings of the Codepen app (at the top right, go to Settings, HTML, Stuff for <head> for the link tag and Settings, JavaScript, copy the link of the src attribute into the Add External Scripts/Pens section for the Test Suite)
    • The HTML in Codepen doesn’t need a <body> tag as it’s already wrapped in one, so you can get rid of it
    • In both the HTML and the JavaScript parts, there were a few code inconsistencies such as spacing and sentence endings (JS). One way to fix it when you bring your code onto Codepen is by highlighting everything and then clicking the dropdown at the top right of the editor and then “tidy …” This will normalize everything to Codepen standards.
  2. App usability

    • For each of the “buttons,” I’d recommend changing the cursor from the typing icon, to a pointer icon, and the rest to the default icon since you can’t manually type anything. To do that, read this.
    • The play, pause, and restart buttons work fine (except for one note with the start_stop below). One jarring thing to me is that if the timer is running and you choose to increase any of the lengths, the timer will snap to the time being changed and reset on that specific value. If I had 2 minutes left on a Session and just decided to change my break time from 5 minutes to 10 minutes, my timer would suddenly jump to the Break and start instantly.
    • I love the “meow meow” song that plays after the timer ends, however, I think it would be nice to have a mute or stop button for the alarm since it’s a nearly 15-second long audio clip. (just preference though)
    • If I click anywhere on the span of the buttons and not the buttons themselves, it will still run the startStop() fx. Not totally a big issue as the functionality is pretty much the same either way, but figured I’d mention it.
  3. The JavaScript

    • Why do you have the Babel preprocessor applied if you’re not using any code that requires it?
    • Since the section you’re working on is mainly about front-end technologies and not basic HTML, CSS, JS, I’d recommend switching the project over to React. This would make a lot of tedious things really simple, such as connecting the time with the document. Obviously not required though.
    • Make sure your timer is presenting the time in mm:ss. For any time the time left reads as a single digit, that would make the Testing Suite fail. For ex. 0:19 is wrong and 00:19 is correct.
    • Make sure when your timer hits 0 and moves to the next time, it starts at the full time. When I used it with a session/break length of both ‘1,’ the timer would be set to 0:59 instead of 01:00.
    • I recommend creating a new Audio() object rather than hard coding the alarm into the HTML. This keeps it a bit more dynamic as you don’t have to query the DOM for it, but isn’t really necessary.

I’m curious after working with what I mentioned in the Usability and JavaScript sections how many tests end up passing as a result :thinking: Lemme know!

2 Likes

If I set work to 1 and break to 1 then hit play it goes straight to break time. Work time should count down first. It appears that the tests count down from one so that could be a problem. Hitting your reset button doesn’t reset it to work time, it resets to break time 25.

I applaud you for a vanilla javascript attempt. I used React but have thought about trying it vanilla. @huntinghawk1415 has provided a very thorough response. And like him I wondered why you did not use React since this section is about learning frontend libraries and they recommend using one. But not required.

About count down not reaching zero @huntinghawk1415 alluded to it I think it has to reach 00:00 rather than 0:00.

2 Likes

Thank you so much for the thorough feedback! Looking forward to diving into these details tomorrow.

2 Likes

Thank you for taking a look! I’ll start making edits on the project tomorrow.

After completing all the React challenges (and multiple other tutorials), React still had not clicked for me. I’m not very interested in pursuing frontend dev, so rather than spending even more time on React, I am using these projects to solidify my JS and problem solving skills. :slight_smile:

1 Like

I did this one with jQuery, and then with React, and then went back to basics and rebuilt it with vanilla js as well.

One bit of advice? Break it down. Rather than trying to create the entire thing as a series of functions handling buttons, create some components. As an example, a Timer component:

  • Handles its own timer display element, updating as needed.
  • Can trigger custom events, like timer.tick or timer.complete, allowing other components to listen and respond.
  • Encapsulates the timer code, simplifying it to methods: timer.start(), timer.pause(), timer.reset(), and getters/setters: timer.time, timer.title.

I did the same with a Counter class, with functions for increment, decrement and reset. By creating these as components, I could simply say

// This will be the listener for the Session Counter
const updateTimer = () => pomodoroTimer.time = this.value*60;

// Let's make all three widgets!
const pomodoroTimer = new Timer({
  time: 25,
  title: 'Session:',
  format: 'mm:ss'
})
const breakCounter = new Counter({
  default: 5,
  title: 'Break Length'
});
const sessionCounter = new Counter({
  default:25,
  title: 'Session Length',
  onIncrement: updateTimer,
  onDecrement: updateTimer
})
// The next lines insert the complete DOM elements for components, and wire everything in.
pomodoroContainer.appendChild(sessionCounter.domEl)
pomorodoContainer.appendChild(breakCounter.domEl);
pomodoroContainer.appendChild(pomodoroTimer);

I think getting comfortable with classes/objects will help a LOT with a solid understanding of frameworks in general, and of React in particular. While you may never choose to work with react, hvaing an understanding of how it works will definitely give you a deeper understanding of javascript in general.

In getting as long-winded as I did, I realized I’d forgotten why I would suggest creating this one as components. By doing so, I can test each part in isolation before introducing it to the larger application. If I create that Counter class, and I test the BEJABBERS out of it, and it responds in a sane and consistent way, then when I place it into my pomodoro, I know what to expect!

2 Likes