Tech Blog

Facebook Icon Twitter Icon Linkedin Icon

AnyMind Group

Facebook Icon Twitter Icon Linkedin Icon

[Tech Blog] Should we use Angular Route Resolver?

When developing an application with Angular, we are basically fetching data from the API with the ngOnInit hook, and then rendering it to the UI. While waiting for the api to return the complete data, the component renders the loading, skeleton. etc

We still have another way to get the data first and then redirect your component. It’s call Route Resolver.

In this article, I will share with you what is Route Resolver is and how to use it and apply it in a real-life case, should we use it or not.

So what is Angular Resolver?

Angular Route Resolver is used for pre-fetching some of the data when the user is navigating from one route to another. It can be defined as a smooth approach for enhancing user experience by loading data before the user navigates to a particular component.

Example simple flow how Resolver work

1. How to create simple Resolver

One simple Resolver to get detail of Site:

@Injectable({
  providedIn: 'root',
})
export class SiteSettingResolver implements Resolve<any> {
  constructor(private siteService: SiteService,
              private router: Router) {
  }

  handleError(error) {
    this.router.navigateByUrl('/404');
    return throwError(error);
  }

  resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<{ site: Site }> {
    const siteID = route.paramMap.get('id');
    if (!siteID) {
      setTimeout(() => {
        this.router.navigate(['/404']);
      }, 500);
    } else {
      return this.siteService.detail(siteID).pipe(
        map(resp => {
          return {site: resp as Site};
        }),
        catchError(err => this.handleError(err))
      );
    }
  }
}

Next we are config router for Site Setting Module:

{
    path: 'site-settings',
    component: SiteSettingsComponent,
    resolve: { preFetchData: SiteSettingResolver }
}

This is Site Setting Component show us how to get data from Resolver:

constructor(private activatedRoute: ActivatedRoute) {}

get site(): Site {
    return this.activatedRoute.snapshot.data.preFetchData.site;
}

Now imagine an HTTP request response data in 5 seconds. After clicking a link in the application, the HTTP request starts. Routing will not be completed before that HTTP request responds with data. Therefore, if HTTP takes 5 seconds, it will also take 5 seconds for routing to complete.

2. What if we don’t use Resolver

So how about the usual way (Fetch the detail data of the Site in the ngOnInit hook in the component without using the resolver)?

This time. The navigation will run right through the site details page without a hitch. Furthermore, our component should add a loading indicator, skeleton loading, etc for user experience purposes.

This is example one component I don’t use Resolver. I added loading so that the user knows and waits for the data to load.

ngOnInit(): void {
    this.loading.show();
    this.siteService.detailSiteWeb(siteId)
        .subscribe((resp: Site) => {
            this.loading.hide();
            this.site = resp;
    }, err => {
        this.router.navigateByUrl('/404');
    });
}

Example simple flow when we don’t use Resolver

3. Conclusion

So with this article we can understand about how Resolver work. In my opinion any Application should be run fast and the data should load asynchronously at runtime. So we may need to consider carefully before using Resolver.

In current project I’m working on which is AnyManager I’m not using much Resolver. I’m just use a resolver when I want to fetch data even before the user is directed to the URL. The resolver can include service calls that will give us the data needed to load the next page.

Here’s what we may need to keep in mind when deciding to use Resolvers:

  • If the Resolver is not resolved, you will not be able to see your component rendered. So if you use Observable, and Observable may never complete then you won’t be able to navigate to the page.
  • Do not share between multiple resolvers together.

Therefore, for streams that return multiple values, you should not use resolvers.
In my opinion, we should only use Resolver to get part of the data, then the component will continue to execute other connections.

Ref:

Latest News