← Back to Web app developers

Skill · Version 1.0.0

Angular components and injection

Separates presentation, coordination and services with explicit dependency scopes and lifecycle cleanup.

angular-components-di

Team members using this skill

See how it helps

When is it useful?

Use when large components or duplicated service instances make state and behavior difficult to understand.

What does it help you do?

  • Defines typed component inputs and outputs without template-driven business effects.
  • Chooses application, route or component service lifetimes deliberately.
  • Cleans up timers, subscriptions, listeners and external instances when ownership ends.

Try asking this

Split our order screen into focused components and explain which services should survive navigation and which should be recreated. Navigate away and back with an unsaved order. Verify which draft state is intentionally retained and that component-owned listeners are released.

Detailed documentation

Read the skill’s original instructions, examples and checks in their authored language.

Details…Show less

Angular Components & Dependency Injection

Keep components focused on presentation and user interaction, and organize services and providers with explicit boundaries, injector scopes and lifetimes.

1. Component boundaries and inputs/outputs

  • Split smart/container components (which coordinate routes, services and state) from presentational components (which receive inputs and emit outputs).
  • Match the project's input/output style (input() / output() / model() in modern Angular, or @Input() / @Output() where standard); keep inputs immutable from the child's perspective.
  • Never put business side effects, HTTP calls or heavy computation inside template expressions or property getters called on every change-detection cycle; use computed(), pure pipes or derived streams instead.
  • Follow the project's ChangeDetectionStrategy (OnPush where used); never paper over stale views with arbitrary ChangeDetectorRef.detectChanges() without finding why the input reference, signal or async pipe did not notify Angular.

2. Dependency injection and provider scopes

  • Follow the project's DI style (inject() function vs constructor injection) consistently.
  • Choose the narrowest appropriate provider scope and understand instance lifetime:
    • providedIn: 'root': app-wide singletons (auth, API clients, global caches) that live for the application's lifetime; ensure they do not retain stale feature state across route or user changes.
    • Route providers: [...]: feature-scoped services shared across a route subtree and destroyed when leaving the route.
    • Component providers: [...] / viewProviders: [...]: per-component instance state (complex form coordinators, local facade services) destroyed with the component (ngOnDestroy / DestroyRef).
  • Never accidentally provide a stateful singleton service in both root and a component's providers array unless a separate per-component instance is deliberate.
  • Use InjectionToken<T> for configuration objects, environment values and abstract contracts.

3. Lifecycle and resource cleanup

  • Register cleanup for timers, manual subscriptions, DOM listeners and third-party instances using DestroyRef.onDestroy(...), takeUntilDestroyed(), or ngOnDestroy().

Before you finish

  • Components have a single clear responsibility and typed inputs/outputs.
  • No side effects or expensive calculations inside template expressions or getters.
  • Every service is provided at the intended scope (root, route, or component) without accidental duplicate instances.
  • Component and service resources clean up on destroy.

Included files 2

  • LICENSE.txt
  • SKILL.md