Angular RouteReuseStrategy

Angular 2/4 components are reloaded when the route is changed. To prevent this we can  implement the RouteReuseStrategy in our application to keep the state of the components while we jump around in our routes.

First we create our class that implements the RouteResuseStrategy. The first object we declare is “routesToCache” which contains the routes that we should reuse. We could cache all routes but that seems like waste of good memory.

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

export class CustomReuseStrategy implements RouteReuseStrategy {

    // Specify the routes to reuse/cache in an array.
    routesToCache: string[] = ["dashboard", "spd/customer"];

    storedRouteHandles = new Map<string, DetachedRouteHandle>();

    // Decides if the route should be stored
    shouldDetach(route: ActivatedRouteSnapshot): boolean {
        return this.routesToCache.indexOf(this.getPath(route)) > -1;
    }

    //Store the information for the route we're destructing
    store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
        this.storedRouteHandles.set(this.getPath(route), handle);
    }

    //Return true if we have a stored route object for the next route
    shouldAttach(route: ActivatedRouteSnapshot): boolean {
        return this.storedRouteHandles.has(this.getPath(route));
    }

    //If we returned true in shouldAttach(), now return the actual route data for restoration
    retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
        return this.storedRouteHandles.get(this.getPath(route)) as DetachedRouteHandle;
    }

    //Reuse the route if we're going to and from the same route
    shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
        return future.routeConfig === curr.routeConfig;
    }

    // Helper method to return a path,
    // since javascript map object returns an object or undefined.
    private getPath(route: ActivatedRouteSnapshot): string {
        let path = "";
        if (route.routeConfig != null && route.routeConfig.path != null)
            path = route.routeConfig.path;
        return path;
    }

}

Then we add the class as a provider in our module.

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { RouterModule, RouteReuseStrategy } from '@angular/router';

import { CustomReuseStrategy } from "./custom.reuse.strategy";

import { AppComponent } from './components/app/app.component';

@NgModule({
    declarations: [
        AppComponent,
    ],
    providers: [
        {
                provide: RouteReuseStrategy,
                useClass: CustomReuseStrategy
            }
        ]
    ],
    imports: [
        CommonModule,
        HttpModule,
        FormsModule
    ]
})
export class AppModuleShared {
}

There you go… Have fun and reuse with caution 🙂

Leave a Comment

Your email address will not be published. Required fields are marked *