Fixing a State Bug and Mapping the Time Remaining Object into the Clock Component
Welcome back to the application. In the last video, we made a couple changes to our app, but we also hit a bug. I'm about to tell you how to fix that bug.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

I saw that I accidentally said var timer, and that's dumb because we need to be accessing the same timer throughout our application or our component here. So let's change this to this.timer, and go down here and say this.timer.

If you do it now, it's still not going to work, but again it comes back to binding functions. We just have to bind the function in our timer. This might be hard to see, so I will reformat my code using option + shift + f. I just moved my code to reformat it. You'll see that there is a whole interval object here. Here to here.

large

What we need to do is look at this function and bind it. There's a function within the setInterval call, and it ends right here. We just have to say: .bind(this). That should make it work.

large

Now we also don't want to be setting state active to true, we want this to be time remaining, so let's go here and let's get rid of active, and let's just say: this.setState({ timeRemaining }) since we set that object right here.

large

Now, timeRemaining is going to be set in our state, and then we can print it out right here with console.log. We also don't want to clear the interval x, we want to clear the interval of this.timer, since we renamed it from x to timer.

large

Let's go to the application in the browser now, select a date a couple days in the future, and hit generate. You'll see it's now counting down, and it's in our state. We have access to it.

large

So super simple error. It will happen to you all the time. It's always just a little thing like saying: "Oh, I missed it. It's not timer, it's this.timer." Obviously, because we want to manipulate the one across the instance of the app.

Let's move on from that. Let's just do that in this video, since that was such a small error. What we want to do is put these days, hours, minutes, and seconds into our clock and have it countdown here and not just in the console. So I'm going to close out of my console, because we aren't really going to be looking at that anymore.

Let's also get rid of the console.log right here.

large

Let's now put that into our clock. Now that we have a whole object in our state, you see that we print it out by saying this.state.timeRemaining. We can easily provide that to our clock by going into our clock here, line 81ish, and saying something like:

app.js

renderItems = function() {
    if (this.state.active) {
      return [
        <Clock timeRemaining={this.state.timeRemaining} />,
        ChangeDate("Change Date", () => this.setState({ active: false })),
        LargeText("04/03"),
        <label className="grid__remaining">
          Remaining until your 21st birthday
        </label>
      ];

This won't just magically appear in our clock. It's not going to be rendering it, becaue we are not doing anything with this prop. So let's go into our clock.js component. I'm going to command + click into it, and instead of saying 300 right here for days, I'm going to say:

clock.js

            <div className="clock">
                <div className="clock__days clock__box">
                    <label className="clock__title">DAYS</label>
                    <label className="clock__amount">{this.props.timeRemaining.days}</label>
                </div>

Now if you back to app.js, and you scroll up, you will see that we call that days, and up in our constructor we call it days. That's going to work. Let's go check it out. Let's select a couple days in the future, hit generate, and you'll see that it has the days.

large

That's really awesome, although, none of these are working. Let's go add that in. Let's go into our clock.js, and instead of typing this out a million times, let's just type it out once and say that variable and .days and .hours and so on.

Let's go here, let's cut that out, let's paste it above our return statement, get rid of the braces, and let's say:

clock.js

    render() {
        const time = this.props.timeRemaining;
        return (
            <div className="clock">
                <div className="clock__days clock__box">
                    <label className="clock__title">DAYS</label>
                    <label className="clock__amount">{time.days}</label>
                </div>
                <div className="clock__hours clock__box">
                    <label className="clock__title">HRS</label>
                    <label className="clock__amount">{time.hours}</label>
                </div>
                <div className="clock__minutes clock__box">
                    <label className="clock__title">MINS</label>
                    <label className="clock__amount">{time.minutes}</label>
                </div>
                <div className="clock__seconds clock__box">
                    <label className="clock__title">SECS</label>
                    <label className="clock__amount">{time.seconds}</label>
                </div>
            </div>

This should work. Let's check it. A couple days out in advance, okay it's reloading, a couple days in advance, and you'll see that it works great. That completes the timer.

large

So, that's how you build that. Let's look at a couple months in the future. It's freaking out a little bit. It's because we didn't clear our interval, our timer. In the next video, I will show you how we can fix this issue.

Let's commit our code. Let's hit command + j in visual studio code. Let's say git status, git add ., and let's say git commit -m "fixed timer state bug, and got timer object into clockjs JSX". Again, JSX is basically our HTML here. It looks like HTML, but it's actually JavaScript. It's known as JSX. See you in the next video

Resources