The Declarative Pattern for Autosave

Learn about the declarative pattern for autosave.

Let's think of the save operation as a stream; it’s the result of the this.service.saveRecipe(formValue) method, which calls this.http.post<Recipe>(`${BASE_PATH}/recipes/save`, formValue. We’ll call it the saveRecipe$ observable. The saveRecipe$ observable is responsible for saving the data in the backend. It will initiate the http request when subscribed to.

What we can do in this situation to avoid nested subscriptions is map or transform the form value emitted by the valueChanges observable to the saveRecipe$ observable. The result is what we call a higher-order observable. Not clear? Don't worry, we’ll explain this in detail in the next section. So, what’s a higher-order observable? And how can it help us in this situation?

Higher-order observables

A higher-order observable is just an observable like any other, but its values are observable as well. In other words, it emits observables that we can subscribe to separately. Okay, but when is it useful?

We can create a higher-order observable whenever we use data emitted from one observable to emit another observable. In our case, for every emitted form value from the valueChanges observable, we want to emit the saveRecipe$ observable. In other words, we want to transform or map the form value to the saveRecipe$ observable. This would create a higher-order observable where each value represents a save request. In this situation, the valueChanges observable is called the outer observable, and saveRecipe$ is called the inner observable. We then want to subscribe under the hood to each saveRecipe$ observable emitted and receive the response all in one go to avoid nested treatments. The following figure illustrates the explanation:

Get hands-on with 1400+ tech skills courses.