DEV Community

Gaëtan Redin
Gaëtan Redin

Posted on • Originally published at Medium on <time datetime="2021-09-03T15:30:55Z" class="date-no-year">Sep 3</time>

Using Angular Resolver to Pre Load Data

Angular for Everyone: Part 13

How to Preload Data for Routed Component in Angular

Hey, you know that one goal of new web developments is to make smoother data loading and content rendering. That’s now easy, thanks to Observables. But in some cases, we need to load the data before reaching a route:

  • Generic components which don’t care about the source of the data
  • We don’t want to display a page’s block if the necessary data are not loaded
  • Separation of concerns

That’s why we need to know that Angular Routing provides a resolve feature that allows pre-load data before the end of the navigation.

First, what does Angular provide us for this feature?

interface Resolve<T> {
  **resolve** (route: ActivatedRouteSnapshot, 
          state: RouterStateSnapshot)
  : Observable<T> | Promise<T> | T;
}
Enter fullscreen mode Exit fullscreen mode

Yes, we need to create a class that implements this interface. designed the expected returned type.

Second, let’s implement our own resolver:

// feature4.resolver.ts

Injectable({
    providedIn: 'root',
})
_export class Feature4_Resolver _implements Resolve_<_any_> {
  constructor(private _myService: MyService) {}

  _public_ resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<_any_> { 
    return this._myService.getMyEntity();
  }
}
Enter fullscreen mode Exit fullscreen mode

Here, I use any as type, please don’t do this. Give a real type. We are using Typescript, and this is just a learning purpose.

Third, let’s use it:

_const_ routes: _Routes_ = [
  {
    path: ':code',
    component: Feature4Component,
    resolve: {
      **myData** : Feature4Resolver,
    },
    ...
  }
];
Enter fullscreen mode Exit fullscreen mode

At last, let’s get the data into our component:

@Component({
  ...
})
_export class_ Feature4Component _implements OnInit_ {
  ...

  _get_ data(): Observable<_any_> {
    _return this_._activatedRoute.data.pipe(_map_((data: _Data_) => data. **myData** ));
  }

  _constructor_(_private_ _activatedRoute: ActivatedRoute) {}
  ...
}
Enter fullscreen mode Exit fullscreen mode

Tip: note the location of your resolver in your routing module is important. If you want to access to myData into Feature4Component’s children, you will have to use the parent ActivatedRoute data: this._route.parent.data.

Conclusion

As you can see, the component doesn’t care about the service, which is called the data. It just gets it from the routing data. So it allows to do great things and to more separate concerns. BUT you have to know that the navigation will be blocked until the resolver has returned anything. So it’s not advised to use this feature for long, complex operations. The usual, adapt the implementation of your solution from your need, not the other way around.

Thanks for reading.

You can find the source code here:

GitHub - GaetanRdn/medium-angular: This project is a support for my medium articles.

Learn More

Discussion (0)