RouteReuseStrategy for Route Caching in Angular

This post explains how to implement RouteReuseStrategy to support custom control of route snapshot caching in Angular. Typical use case is a list page which a user can search for a list of items and then select and navigates to a particular item’s detail pages. When the user clicks the back button in the browser, the Angular app should return to the list page displaying the same items as before, using the previous search criteria.

Other advantages of caching route for rendering is faster page load and reduce network traffic.

To achieve the above in Angular, we need to implement the RouteReuseStrategy to tell Angular not to destroy a component but to save it for re-rendering. There are few blog posts online already with example implementations. This blog will focus more on describing the mechanics of the interface and its methods

RouteReuseStretagy

Below is a skeleton implementation of a custom RouteReuseStrategy:

import { Injectable } from '@angular/core';
import { RouteReuseStrategy, ActivatedRouteSnapshot, DetachedRouteHandle } from '@angular/router';

@Injectable()
export class AppRouteReuseStrategyService implements RouteReuseStrategy {

     handles: {[key: string]: DetachedRouteHandle} = {};

     constructor() { }

     shouldDetach(route: ActivatedRouteSnapshot): boolean {
           // To Be Implemented
     }

     store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
           // To Be Implemented
     }

     shouldAttach(route: ActivatedRouteSnapshot): boolean {
           // To Be Implemented
     }

      retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
          // To Be Implemented
      }

      shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
          // To Be Implemented
      }
}

shouldReuseRoute()

This is the first method to consider. If returns true, none of the other methods will be called. For example, when we are already reusing the current route snapshot. Note the future argument refers to the route that you come from previously. For example if the app navigates from item list page to item details page, curr would refer to the route for the item detail page and future to the route for the item list page.

shouldDetach() and store()

If the method shouldRouteReuse returns false, the method shouldDetach will be called to determine whether the current route snapshot should be detached and stored. If it returns true, the store method will be called. A handle to the detached route snapshot (of type DetachedRouteHandle) is provided as argument to the method so it can store it for later use.

Note if a null handle is provided to the method, it should erase the stored value for the input route. See the API documentation here.

Note once a route snapshot is detached, it is the developer’s responsibility to manage its lifecycle and perform any clean up as needed for proper memory management.

shouldAttach() and retrieve()

Similar to above,

If the method shouldReuseRoute returns false, the method shouldAttach will be called to determine if a cached route should be used. If it returns true, the method retrieve will be called to retrieve the saved handle to the detached route previously stored.

Note the shouldAttach method is also a good place to clean up any stored snapshots. For example when a user has logged out or the snapshot has got staled, in which case we should not be rendering the store snapshot. The method should then return false and the stored handle to route snapshot should be removed from storage.

That’s it. Hope above gives some clarity on what the class RouteReuseStrategy does.

Advertisements