
Pausing an exercise
To pause an exercise, we need to stop the timer. We also need to add a button somewhere in the view that allows us to pause and resume the workout. We plan to do this by drawing a button overlay over the exercise area in the center of the page. When clicked on, it will toggle the exercise state between paused and running. We will also add keyboard support to pause and resume the workout using the key binding p or P. Let's update the component.
Update the WorkoutRunnerComponent class, add these three functions, and add a declaration for the workoutPaused variable:
workoutPaused: boolean;
... pause() { clearInterval(this.exerciseTrackingInterval); this.workoutPaused = true; } resume() { this.startExerciseTimeTracking(); this.workoutPaused = false; } pauseResumeToggle() { if (this.workoutPaused) { this.resume(); } else { this.pause(); } }
The implementation for pausing is simple. The first thing we do is cancel the existing setInterval setup by calling clearInterval(this.exerciseTrackingInterval);. While resuming, we again call startExerciseTimeTracking, which again starts tracking the time from where we left off.
Now we just need to invoke the pauseResumeToggle function for the view. Add the following content to workout-runner.html:
<div id="exercise-pane" class="col-sm-6"> <div id="pause-overlay" (click)="pauseResumeToggle()"> <span class="pause absolute-center"
[ngClass]="{'ion-md-pause' : !workoutPaused, 'ion-md-play' : workoutPaused}">
</span>
</div> <div class="row workout-content">
The click event handler on the div toggles the workout running state, and the ngClass directive is used to toggle the class between ion-md-pause and ion-md-play- standard Angular stuff. What is missing now is the ability to pause and resume on a P key press.
One approach could be to apply a keyup event handler on the div:
<div id="pause-overlay" (keyup)= "onKeyPressed($event)">
But there are some shortcomings to this approach:
- The div element does not have a concept of focus, so we also need to add the tabIndex attribute on the div to make it work
- Even then, it works only when we have clicked on the div at least once
There is a better way to implement this; attach the event handler to the global window event keyup. This is how the event binding should be applied on the div:
<div id="pause-overlay" (window:keyup)= "onKeyPressed($event)">
Make note of the special window: prefix before the keyup event. We can use this syntax to attach events to any global object, such as the document. A handy and very powerful feature of Angular binding infrastructure! The onKeyPressed event handler needs to be added to WorkoutRunnerComponent. Add this function to the class:
onKeyPressed(event: KeyboardEvent) {
if (event.which === 80 || event.which === 112) {
this.pauseResumeToggle();
}
}
The $event object is the standard DOM event object that Angular makes available for manipulation. Since this is a keyboard event, the specialized class is KeyboardEvent. The which property is matched to ASCII values of p or P. Refresh the page and you should see the play/pause icon when your mouse hovers over the exercise image, as follows:

While we are on the topic of event binding, it would be a good opportunity to explore Angular's event binding infrastructure