Documentation Index Fetch the complete documentation index at: https://mintlify.com/akbarsaputrait/ngememoize/llms.txt
Use this file to discover all available pages before exploring further.
This guide will get you up and running with Ngememoize quickly. You’ll learn how to memoize both synchronous and asynchronous functions with practical examples.
Basic memoization
Import the decorator
Start by importing @Ngememoize in your component or service: import { Component } from '@angular/core' ;
import { Ngememoize } from 'ngememoize' ;
Add the decorator to a method
Apply @Ngememoize() to any method you want to cache: @ Component ({
selector: 'app-product' ,
standalone: true ,
template: '...'
})
export class ProductComponent {
@ Ngememoize ()
calculateSubtotal ( price : number , quantity : number ) : number {
console . log ( 'Computing subtotal...' );
return price * quantity ;
}
}
Now when you call calculateSubtotal(100, 2) multiple times with the same arguments, the calculation only runs once.
Test the cache
Call your memoized method multiple times: // First call - executes the function
const result1 = this . calculateSubtotal ( 100 , 2 ); // Logs: "Computing subtotal..."
console . log ( result1 ); // 200
// Second call - returns cached result
const result2 = this . calculateSubtotal ( 100 , 2 ); // No log!
console . log ( result2 ); // 200 (instant)
// Different arguments - executes the function again
const result3 = this . calculateSubtotal ( 50 , 3 ); // Logs: "Computing subtotal..."
console . log ( result3 ); // 150
Memoizing getters
You can also memoize getters to cache computed properties:
import { Ngememoize } from 'ngememoize' ;
export class UserComponent {
users : User [] = [];
@ Ngememoize ()
get adminUsers () : User [] {
console . log ( 'Filtering admin users...' );
return this . users . filter ( user => user . role === 'admin' );
}
}
The getter result is cached until the component state changes.
Getters are memoized without arguments. The cache is based on the context in which they’re called.
Async function memoization
Ngememoize works seamlessly with async functions and Promises:
import { Ngememoize } from 'ngememoize' ;
export class DataService {
@ Ngememoize ({
maxAge: 5000 , // Cache for 5 seconds
debugLabel: 'fetchData'
})
async fetchData ( id : string ) : Promise < string > {
console . log ( 'Fetching data from API...' );
const response = await fetch ( `/api/data/ ${ id } ` );
return response . json ();
}
}
Subsequent calls within 5 seconds return the cached Promise result instantly.
Adding cache expiration
Control how long results stay cached using the maxAge option:
@ Ngememoize ({
maxAge: 5000 // Cache expires after 5 seconds
})
calculateDiscount ( subtotal : number , code : string ): number {
console . log ( 'Computing discount...' );
if ( code === 'SAVE10' ) return subtotal * 0.1 ;
if ( code === 'SAVE20' ) return subtotal * 0.2 ;
return 0 ;
}
After 5 seconds, the cache is invalidated and the function runs again on the next call.
Custom cache keys
By default, Ngememoize generates cache keys from all arguments. You can customize this:
@ Ngememoize ({
keyGenerator : ( price , quantity ) => `subtotal- ${ price } - ${ quantity } `
})
calculateSubtotal ( price : number , quantity : number ): number {
return price * quantity ;
}
This is useful when you want explicit control over what makes results unique.
Debugging cache behavior
Use the debugLabel option to see cache hits and misses in the console:
@ Ngememoize ({
debugLabel: 'calculateShipping' ,
onCacheHit : ( key ) => console . log ( `✅ Cache hit for ${ key } ` ),
onCacheMiss : ( key ) => console . log ( `❌ Cache miss for ${ key } ` )
})
calculateShipping ( method : string , subtotal : number ): number {
switch ( method ) {
case 'express' : return subtotal > 100 ? 10 : 15 ;
case 'overnight' : return subtotal > 150 ? 20 : 25 ;
default : return 0 ;
}
}
Now you’ll see logs like:
[Memoize: calculateShipping] Cache miss for key: express-150
❌ Cache miss for express-150
[Memoize: calculateShipping] Cache hit for key: express-150
✅ Cache hit for express-150
Real-world example
Here’s a complete example from a product pricing component:
import { Component , inject } from '@angular/core' ;
import { Ngememoize , NgememoizeService } from 'ngememoize' ;
@ Component ({
selector: 'app-product' ,
standalone: true ,
template: '...'
})
export class ProductComponent {
memoizeService = inject ( NgememoizeService );
product = {
basePrice: 100 ,
quantity: 2 ,
discountCode: 'SAVE10' ,
shipping: 'express'
};
@ Ngememoize ({
maxAge: 5000 ,
keyGenerator : ( price , quantity ) => `subtotal- ${ price } - ${ quantity } ` ,
onCacheHit : ( key ) => console . log ( `🎯 Cache HIT: ${ key } ` ),
onCacheMiss : ( key ) => console . log ( `📝 Cache MISS: ${ key } ` )
})
calculateSubtotal ( price : number , quantity : number ) : number {
console . log ( '💰 Computing subtotal...' );
return Number (( price * quantity ). toFixed ( 2 ));
}
@ Ngememoize ()
calculateDiscount ( subtotal : number , code : string , quantity : number ) : number {
console . log ( '🏷️ Computing discount...' );
if ( code === 'SAVE10' ) return Number (( subtotal * 0.1 ). toFixed ( 2 ));
if ( code === 'SAVE20' ) return Number (( subtotal * 0.2 ). toFixed ( 2 ));
if ( code === 'BULK15' && quantity >= 5 ) return Number (( subtotal * 0.15 ). toFixed ( 2 ));
return 0 ;
}
@ Ngememoize ()
calculateShipping ( method : string , subtotal : number ) : number {
console . log ( '📦 Computing shipping...' );
if ( method === 'express' ) return subtotal > 100 ? 10 : 15 ;
if ( method === 'overnight' ) return subtotal > 150 ? 20 : 25 ;
return 0 ;
}
calculateTotal () {
const subtotal = this . calculateSubtotal (
this . product . basePrice ,
this . product . quantity
);
const discount = this . calculateDiscount (
subtotal ,
this . product . discountCode ,
this . product . quantity
);
const shipping = this . calculateShipping (
this . product . shipping ,
subtotal
);
return subtotal - discount + shipping ;
}
}
Use inject(NgememoizeService) to access cache statistics and inspect all cached values. This is helpful during development.
Next steps
Now that you understand the basics, explore more advanced features:
Advanced options Learn about all decorator options
Cache management Control cache size and lifetime
Custom key generators Create advanced caching strategies
Debugging Monitor cache performance and troubleshoot issues