Angular: What is a Resolver and When to Use It.
Angular 4 has a few differences from Angular 1 (Now they are called Angular and AngularJS respectively) that makes it almost a different framework. Working with it has caused me to learn a few new things and I wanted to explain a few of the differences.
One of the differences is using resolvers in your application.
What is a Resolver?
So before we talk about why and when you use a resolver, I guess it would be best to understand what it is.
Simply speaking a resolver is a way to cause a component to wait to render until it has the all the data it needs. I am sure we have all gone to a website and had part of the page load and then had to wait a few seconds before the rest of the page renders. This can cause the layout of the page to be wrong or look broken.
The idea of a resolver in Angular is to fix this.
Why would you use a Resolver?
The main reason is to make a more smoother experience for a user on the site. By using it you are causing the component to wait. It allows all the data to be there when the page renders. If you have a lot of data that you are calling through an API then this will make for a better experience.
How do you use a Resolver?
Now we can get to the good stuff. Honestly, Angular is quite a learning curve and it takes a little more boilerplate to get most things working and you have to do it the "Angular way". Don't get frustrated... it just takes some practice.
So how do we do this?
Well.. first we have to look at routing in Angular. As you can see below Angular uses imports for dependencies and then uses an array of objects for the paths. So in the code below the path
reports would cause Angular to look for
www.URL.com/reports and then render the component
ReportsComponent that it is importing. You can see this on line 8.
You can learn more about routing in the Angular docs.
So this will then call the
ReportsComponentand render it for the user. However, the component HTML might load before all the API calls complete. This is the issue that resolvers solve.
So lets create a resolver for this:
So here is part of the resolver. It imports a few Angular specific dependencies that are needed. It returns a
Resolve type so that has to be imported and it needs the
ActivatedRouteSnapshot which is another Angular dependency that gets imported. The
ReportService is making our ajax call for us so it gets imported to abstract that functionality away.
The bottom line is that this file is performing our API call to get data and then returning it as a
resolve type for whatever instantiates it. This is what Angular needs in the router to send the data along. The Angular docs are pretty good with details on this as well.
Next we need to import our new resolver and apply it to our route so that Angular will run it before rendering the component:
So we import our newly created resolver (it simply calls our other service to make an API call and returns it) and we add it to the path for the router. We need to use
resolve which is an Angular dependency and does all the work behind the scenes to send the data along. You also give it a name and in our case we are using
questionBanks because this specific resolver return a list of question banks for the report component to use. This name is how we will reference the data that comes along the router in the component so we can look at that next.
We now need to get the data from the route into the component so that we can use it. By doing this through the resolver the data will be there (as long as the API call doesn't fail) as soon as the component is rendered.
Here is how you do that in the component:
You import the
ActivatedRoute and then provide that in the constructor. (One thing to note is that by passing in a dependency in the constructor and setting it as
private will cause Angular to make it private with a setter and getter automatically. It might look like some lines are missing but that is what is happening so no worries! :) )
Next you assign the data from the route on the
ngOnInit function which runs on the first lifecycle of the component. You can see this in the line below where we are getting the data and adding it to the public var
tabs. We can then use that in our template however we need to render on the page.
Hopefully this helps with understanding resolvers in Angular. I have to admit that I did assume some knowledge on the Angular ecosystem and skipped a few items that are not directly related to the functionality of setting up a resolver for the sake of brevity.
If you have specific Angular topics (or development in general) you want to discuss then let me know and I would be happy to post my take on it or explore the functionality.
We are all learning!😎