Skip to main content

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

1

Import the decorator

Start by importing @Ngememoize in your component or service:
import { Component } from '@angular/core';
import { Ngememoize } from 'ngememoize';
2

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.
3

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