As we saw at the beginning of the chapter, there are many uses of observables besides an HTTP request. In our task, we will exemplify this use. In a reactive form, a user typing into a field is treated as an observable.
In our example, let’s change the NewEntryFormReactiveComponent component:
ngOnInit(): void {
this.entryForm.valueChanges.subscribe((model) => console.log(model));
}
Running our application, we can see in the browser’s console that typing into any form field triggers an event captured by the subscribe method.
Knowing that we can react to user typing events, how do we connect this event to the search for exercise information in the API? We use an operator!
Back in our component, we will refactor the code:
public exercises$ = this.entryForm.valueChanges.pipe(
switchMap((model) => this.exerciseService.getExercises(model?.exercise))
);
We remove the subscription of the ngOnInit method from the component and put in the assignment of the exercises$ observable. However, if we do this, TypeScript and Angular type validation show an error because the template is waiting for a list to perform the iteration.
Enter the switchMap operator. We exchange the first flow of events for typing the form with the exercise request flow, passing the exercise field of the form model as a filter for the exerciseService service.
The result of this is that the exercises$ observable continues to receive a list of exercises. Executing our project, we notice that we have a list with a typeahead search making the request as we fill in the field, as shown in the following figure.
Figure 9.1 – Selection of exercises
The switchMap operator is a higher-order observable because it takes an observable as input and returns an observable as output. This is in contrast to the map operator, which takes an observable as input and returns a value as output.
With a command, we have our search field, but if we look at our browser’s Network tab, we can see that a request is triggered for every letter we type. We can improve our application’s data consumption without harming our user experience, which we will do in the next section.