Resolver
Resolvers is used to provide data, before activating route, in brief, force the application to show the view only after loading the data. For easier understanding I will show it on the example.
Example of use:
I have a basic value model and I want to display it in the view.
export class Value {
id: number;
name: string;
}
Service for retrieving value from API with passing id parameter in URL.
getValue() {
this.valueService.getValue(+this.route.snapshot.params['id']).subscribe((value: Value) => {
this.value = value;
});
}
Simple view.
<strong class="text-center">
<p>Value:</p>
<p>{{value.Name}}</p>
<p>{{value.Id}}</p>
</strong>
After redirect to http://localhost:4200/value/1, we get error in console.
![]()
But our view loaded correctly. This happens because as I mentioned earlier when rendering the view component value , there is no model to display yet. To fix the error, we can use “elvis” operators.
<strong class="text-center">
<p>Value:</p>
<p>{{value?.Name}}</p>
<p>{{value?.Id}}</p>
</strong>
It solves our error, however it is not recommended to use it often.
So the resolvers come here for help.
To use the resolver, I need to write a service that implements the interface resolve. The resolve method can take two parameters, ActivatedRouteSnapshot and RouterStateSnapshot.
Example of the resolver implementation:
@Injectable()
export class ValueResolver implements Resolve<string> {
constructor(private valueService: ValueService, private router: Router) { }
resolve(route: ActivatedRouteSnapshot): Observable<string> {
return this.valueService.getValue(route.params['id']).pipe(
catchError(error => {
console.log('Error');
this.router.navigate(['/home']);
return of(null);
})
);
}
}
Now I need to register it in app.module.ts in providers.
@NgModule({
...
providers: [
ValueResolver
],
...
})
Then pass the resolver in routing.
const routes: Routes = [
...
{ path: 'value/:id', component: ValueComponent, resolve: { value : ValueResolver } },
...
];
The ActivatedRoute interface gives us access to the ActivatedRouteSnapshot snapshot. It has access to a data object that contains data received from (in our case) resolver.
Let’s use the fact that our resolver returns the object observer and subscribe to it.
ngOnInit() {
this.route.data.subscribe(result => {
this.value = result['value'];
});
}
We refer to the ‘value’ properity because that’s how I set it up in routing.
After changing the view
<strong class="text-center">
<p>Value:</p>
<p>{{value.Name}}</p>
<p>{{value.Id}}</p>
</strong>
everything loads correctly without any errors.
Code available on github.
