At SpotDraft, we absolutely love using Redux with our Angular app, and many pieces of the state are truly global i.e. they are required to configure different pieces of the application and directly read in different components.
Many components directly access the state without worrying about how that state was set, so when exactly was the data loaded into the state?
Since our state was simple, we added these requests to the login action, the user logged in, we loaded a bunch of data and this approach worked well… for some time.
As the features increased, it became very clear that not all the data is required to be loaded at all times and different users (based on features available), require different data to be pre-loaded. We needed a better way to declare data dependencies so that data is loaded into the state as and when it's actually required.
Resolvers are used to pre-load data required by a route. This means that when the user navigates to a route with a resolver, the component on the route is not initialised till the resolvers have loaded the data.
This is what a resolver configuration looks like -
So, resolvers take care of ensuring that a page is rendered only after the data it absolutely needs is loaded, that sounds helpful, only if there was a way to connect this to our state so that we can declare which elements of the state does this route depend on.
To bridge this gap, we came up with a concept of a StateAwareResovler, a fancy name for a fairly simple concept.
A StateAwareResolver, is basically a resolver that works like this -
Angular’s resolvers are interfaces that expose a resolve method. This method can return an Object, or they can return an Observable that emits the object.
The structure of the a StateAwareResolver looks something like -
Note: The NgRedux service is provided by the angular-redux package that we use to interact with the redux store.
A sample implemention of the StateAwareResolver looks like -
In the route config -
In this case, when the user first navigates to the dashboard, the resolver will load the user over HTTP and set it in state, however, when the user navigates to /user, then the component will load immediately as the user is already present in state.
Using this little abstraction, we are not only making it easy to handle our state data dependencies, but also making our API consumption more efficient as any valid data will not be reloaded unnecessarily.