As a developer, we all may have noticed a repetitive boilerplate code of displaying a loader while an asynchronous request is being processed, and then switching to the main view or displaying an error for that particular asynchronous request.
In this blog, we will learn about the Angular View State Selector which helps developers to reduce the repetitive boiler plate from the code.
While working I noticed these repetitions both in my code and with other developers I work with. An even worse scenario than the repetitive code is the fact that there are no indications for missing state views (such as unhandled errors or a missing loader).
The below example is the practical implementation. This code has a main view container, error handling block, a loader template, and some conditions to determine the state of the overall dom.
To resolve this View State Selector comes under working.
About View State Selector
View State Selector is a pattern binding the component state with the corresponding template. In simple words, it looks like we are working with ngSwitchCase.
It automatically administrates a template for a specific component state.
This is one of the examples:-
One Component of a lazy loaded module depends on a data retrieved by an HTTP/API request that goes with a loading state that results in injecting the loader, after that depending on the response state(success or error) it will switch the view.
In this blog, we look into the View State Selector Pattern. Although this pattern can be generalized to choose one of any mutually exclusive views based only on any input state, in the next parts we will concentrate on the most common use case of changing the view according to the asynchronous HTTP state. So let’s dive into it.
UseCase for the View State Pattern
The usage of the “State Selector” pattern is somewhat similar to a ngSwitchCase. Given an input representation of the state render the template matching the provided state:
There are a few cases in which this pattern will have an advantage over using ngSwitchCase in Angular:
- The pattern can be utilized to optimize and reduce the boilerplate code of the conditions that determine the active template (view) of the component.
- It encapsulated all the conditions into the ViewContainer.
- Generally, it works with the more complicated states(states represented by state machines).
- In several scenarios where simply using ngSwitch is possible but will require extra code to convert the state to enum for the ngSwitch cases.
- This works very well while working with complex states or more than a single state at the same time.
States in View State Pattern
View in “View State Selector”* To achieve the goal of a reusable pattern we need to start by defining an interface to store the
View states. In general, a
View is an object representing the states of, well, the view. It can have as many states as your component needs. In this article I am going to focus on the three most used states:
Loading: During the process of calling an API request the loading state comes under the main view. This state will inject the
Loader template into the
Data – This shows upon a (successful) response from the asynchronous request and then the display data will be mapped into the
Error: If the asynchronous/API request gets fails and returns an error then this state comes into the view. It contains an error message.
Implementation of View State Selector Pattern
For implementation, we have to map the state into the view of the state selector. The view state starts with loading and then to the response event when there is a successful response from the API or the error event in case of error occurs.
An observable emitted the view into the DOM.
So we to create a structural directive for ViewContainer. The ViewContainer is responsible for the involvement of the corresponding template.
The implementation for both the Directive and the Component is very similar, I will focus on the Directive implementation.
First, create an empty Directive
ngAfterViewInit we will check that all the templates exist. If one of the templates is missing we will get an error that’s hard to miss.
And to bind the template reference (#<name>) to the properties add:
Finally, each time the View is changed insert the template into the container. For that, we can use createEmbeddedView API So let’s inject the ViewContainerRef Service.
Now, we have everything we need to implement the setter:
In this blog, we check out the implementation of the View State Selector which helps us to simplify the view state of the component.
We also took a look at how we can minimize the boilerplate code. While at the same time reducing the chances for potential bugs by getting some feedback in the form of an error message when something is not present.