Crafting Custom Angular Decorators for Enhanced Functionality

Learn how to create your own decorators in Angular to streamline functionality and improve code readability.

0 likes
43 views

Rule Content

{
  "title": "Crafting Custom Angular Decorators for Enhanced Functionality",
  "description": "Learn how to create your own decorators in Angular to streamline functionality and improve code readability.",
  "category": "Angular Cursor Rules",
  "rules": [
    {
      "name": "Use Custom Decorators to Encapsulate Repetitive Logic",
      "description": "Create custom decorators to encapsulate repetitive logic, reducing boilerplate code and enhancing maintainability.",
      "examples": [
        {
          "before": "class ExampleComponent {\n  ngOnInit() {\n    console.log('Component initialized');\n  }\n}",
          "after": "function LogInit(target: any) {\n  const original = target.prototype.ngOnInit;\n  target.prototype.ngOnInit = function () {\n    console.log('Component initialized');\n    if (original) {\n      original.apply(this);\n    }\n  };\n}\n\n@LogInit\nclass ExampleComponent {\n  ngOnInit() {\n    // Component initialization logic\n  }\n}"
        }
      ]
    },
    {
      "name": "Implement Unsubscribe Decorators to Prevent Memory Leaks",
      "description": "Use custom decorators to automatically unsubscribe from observables, preventing memory leaks.",
      "examples": [
        {
          "before": "class ExampleComponent implements OnDestroy {\n  private subscription: Subscription;\n\n  ngOnInit() {\n    this.subscription = this.someObservable.subscribe();\n  }\n\n  ngOnDestroy() {\n    this.subscription.unsubscribe();\n  }\n}",
          "after": "function AutoUnsubscribe(target: any) {\n  const original = target.prototype.ngOnDestroy;\n  target.prototype.ngOnDestroy = function () {\n    for (const prop in this) {\n      const property = this[prop];\n      if (property && typeof property.unsubscribe === 'function') {\n        property.unsubscribe();\n      }\n    }\n    if (original) {\n      original.apply(this);\n    }\n  };\n}\n\n@AutoUnsubscribe\nclass ExampleComponent {\n  private subscription: Subscription;\n\n  ngOnInit() {\n    this.subscription = this.someObservable.subscribe();\n  }\n}"
        }
      ]
    },
    {
      "name": "Create Input Validation Decorators for Consistent Data Handling",
      "description": "Develop decorators to enforce input validation, ensuring consistent and error-free data handling.",
      "examples": [
        {
          "before": "class ExampleComponent {\n  saveData(data: string) {\n    if (data.length < 5) {\n      throw new Error('Data must be at least 5 characters long');\n    }\n    // Save data logic\n  }\n}",
          "after": "function MinLength(length: number) {\n  return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {\n    const original = descriptor.value;\n    descriptor.value = function (...args: any[]) {\n      if (args[0].length < length) {\n        throw new Error(`${propertyKey} requires a string of minimum length ${length}`);\n      }\n      return original.apply(this, args);\n    };\n  };\n}\n\nclass ExampleComponent {\n  @MinLength(5)\n  saveData(data: string) {\n    // Save data logic\n  }\n}"
        }
      ]
    },
    {
      "name": "Utilize Logging Decorators for Debugging and Monitoring",
      "description": "Implement decorators to log method calls and parameters, aiding in debugging and monitoring.",
      "examples": [
        {
          "before": "class ExampleComponent {\n  fetchData(id: number) {\n    // Fetch data logic\n  }\n}",
          "after": "function LogMethod(target: any, propertyKey: string, descriptor: PropertyDescriptor) {\n  const original = descriptor.value;\n  descriptor.value = function (...args: any[]) {\n    console.log(`Calling ${propertyKey} with arguments:`, args);\n    return original.apply(this, args);\n  };\n}\n\nclass ExampleComponent {\n  @LogMethod\n  fetchData(id: number) {\n    // Fetch data logic\n  }\n}"
        }
      ]
    },
    {
      "name": "Apply Debounce Decorators to Optimize Performance",
      "description": "Use decorators to debounce method calls, optimizing performance by limiting the rate of execution.",
      "examples": [
        {
          "before": "class ExampleComponent {\n  onSearch(query: string) {\n    // Search logic\n  }\n}",
          "after": "function Debounce(delay: number) {\n  return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {\n    const original = descriptor.value;\n    let timeout: any;\n    descriptor.value = function (...args: any[]) {\n      clearTimeout(timeout);\n      timeout = setTimeout(() => original.apply(this, args), delay);\n    };\n  };\n}\n\nclass ExampleComponent {\n  @Debounce(300)\n  onSearch(query: string) {\n    // Search logic\n  }\n}"
        }
      ]
    }
  ]
}