@ravimallya/ng-lazy-cache
v0.1.4
Published
A lightweight Angular route resolver for caching asynchronous data with a configurable time-to-live (TTL). This library optimizes Angular applications by reducing redundant API calls and enhancing performance for route data loading.
Downloads
48
Readme
@ravimallya/ng-lazy-cache
A lightweight Angular route resolver for caching asynchronous data with a configurable time-to-live (TTL). This library optimizes Angular applications by reducing redundant API calls and enhancing performance for route data loading.
Overview
@ravimallya/ng-lazy-cache provides a LazyCache resolver that caches the results of asynchronous data fetches (e.g., HTTP requests) using a unique key. It supports both route-level and global TTL configurations, offering flexible caching strategies. Additionally, a clearCache function is available for testing purposes to reset the in-memory cache.
- Route-Level TTL: Set a specific TTL for individual routes.
- Global TTL: Define a default TTL at the application level, overridden by route-specific values.
- In-Memory Caching: Stores data with automatic expiration.
Installation
Install the package via npm:
npm install @ravimallya/ng-lazy-cacheEnsure your project has the following peer dependencies:
@angular/core(^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0)@angular/common(^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0)@angular/router(^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0)rxjs(~7.8.0 || ^8.0.0)
Usage
Basic Example
Configure the resolver in your route definition to cache data.
import { Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { LazyCache } from '@ravimallya/ng-lazy-cache';
import { of } from 'rxjs';
const fetchData = () => {
console.log('Fetching data...');
return of('Loaded data from server');
};
export const routes: Routes = [
{
path: 'cached-route',
component: HomeComponent,
resolve: {
data: LazyCache(fetchData, { key: 'demo-key', ttl: 5000 }) // 5-second TTL
}
},
{ path: '', redirectTo: '/cached-route', pathMatch: 'full' }
];In your component, access the resolved data:
import { Component } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-home',
standalone: true,
template: `<p>Resolved Data: {{ data }}</p>`
})
export class HomeComponent {
data: string;
constructor(route: ActivatedRoute) {
this.data = route.snapshot.data['data'];
}
}Global TTL Configuration
Set a default TTL in app.config.ts, overridden by route-specific TTLs.
import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
import { GLOBAL_TTL_TOKEN } from '@ravimallya/ng-lazy-cache';
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes),
{ provide: GLOBAL_TTL_TOKEN, useValue: 30000 } // Global TTL of 30 seconds
]
};Route-Level TTL Override
Override the global TTL for specific routes.
export const routes: Routes = [
{
path: 'cached-route',
component: HomeComponent,
resolve: {
data: LazyCache(fetchData, { key: 'demo-key', ttl: 5000 }) // 5-second TTL overrides global
}
}
];Real-World Example with HTTP
Cache API responses using HttpClient.
import { Routes, ActivatedRouteSnapshot } from '@angular/router';
import { ProductComponent } from './product/product.component';
import { LazyCache } from '@ravimallya/ng-lazy-cache';
import { HttpClient } from '@angular/common/http';
import { of } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
import { inject } from '@angular/core';
const fetchProduct = (http: HttpClient, id: string) => () =>
http.get(`https://jsonplaceholder.typicode.com/posts/${id}`).pipe(
map(response => response.title),
catchError(() => of('Fallback Data'))
);
export const routes: Routes = [
{
path: 'product/:id',
component: ProductComponent,
resolve: {
product: LazyCache((route: ActivatedRouteSnapshot) => fetchProduct(inject(HttpClient), route.params['id']), {
key: (route) => `product-${route.params['id']}`, // Dynamic key
ttl: 60000 // 1-minute TTL
})
}
}
];In ProductComponent:
import { Component } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-product',
standalone: true,
template: `<p>Product Title: {{ product }}</p>`
})
export class ProductComponent {
product: string;
constructor(route: ActivatedRoute) {
this.product = route.snapshot.data['product'];
}
}API Documentation
LazyCache<T>(fetchFn: () => Observable<T>, options: LazyCacheOptions<T> = { key: 'default' }): ResolveFn<T>- Parameters:
fetchFn: A function returning anObservablethat fetches the data.options: An object with:key: A string or function(route: ActivatedRouteSnapshot) => stringto generate a unique cache key.ttl?: Optional number (in milliseconds) for route-specific TTL (overrides global TTL).
- Returns: A
ResolveFncompatible with Angular’s router.
- Parameters:
GLOBAL_TTL_TOKEN- An injection token to provide a global TTL (default: 30 seconds) via
app.config.ts.
- An injection token to provide a global TTL (default: 30 seconds) via
clearCache(): void- A utility function to clear the in-memory cache, intended for testing purposes.
Development
Building the Library
ng build ng-lazy-cache --configuration productionRunning Tests
npx ng test ng-lazy-cache --browsers=ChromeHeadlessDemo Application
A demo app is included in the projects/demo-app directory. Serve it to test the library:
ng serve demo-appContributing
- Fork the repository.
- Create a feature branch (
git checkout -b feature/new-feature). - Commit your changes (
git commit -m 'Add new feature'). - Push to the branch (
git push origin feature/new-feature). - Open a pull request.
License
This project is licensed under the MIT License. See the LICENSE file for details.
Acknowledgements
- Built with ❤️ using Angular and RxJS.
- Inspired by the need for efficient route data caching in large-scale applications.
