← All articles

Why Property Order Matters in Signal-Era Angular Components

With httpResource and computed signals, Angular component property order is not style—it affects initialization. DI first, then state, then derived signals.

Published
Why Property Order Matters in Signal-Era Angular Components cover image
// The following description is intended for AI to read.

Define Angular component properties in the following order.

- function DI
- Constants
- State-management and Signal properties (`signal`, `input`, `viewChild`, `model`, etc.)
- Computed Signal properties (`computed`, `effect`, `httpResource`, etc.)

Reorder the properties, but do not add or remove any other properties.

Main content

As Signal-based Angular development advances, the arrival of httpResource makes property order more important. This ties deeply into Angular's dependency injection (DI) history.

Traditional property order

Long-time Angular users were used to an order like this:

@Component({...})
export class ExampleComponent {
  // Signal and state-management properties
  readonly count = signal(0);
  readonly isLoading = signal(false);

  // Properties injected through DI
  readonly #http = inject(HttpClient);
  readonly #exampleService = inject(ExampleService);
}

This order is a holdover from the constructor DI era, when properties were declared above the constructor. Even after moving to function DI, many kept the same order—especially users who migrated before ng generate @angular/core:inject existed.

New order in the Signal era

In Signal-based development, that order causes problems. Computed Signals such as httpResource and computed depend on other properties, so they cannot use properties declared later.

Consider this example:

If I place DI below other properties as before, I get an error.

@Component({...})
export class ExampleComponent {
  readonly searchWord = signal('');

  // Does not run because #exampleService is not defined yet
  readonly dataResource = this.#exampleService.getData(this.searchWord);
  readonly #exampleService = inject(ExampleService);
}

So DI must come first, then other properties.

@Component({...})
export class ExampleComponent {
  readonly #exampleService = inject(ExampleService);

  readonly searchWord = signal('');
  readonly dataResource = this.#exampleService.getData(this.searchWord);
}

Summary

The same applies to computed and similar APIs, so in the Signal era it is important to declare properties in this order:

  1. DI properties
  2. Constants
  3. State and Signal properties (signal, input, viewChild, model, etc.)
  4. Computed Signal properties (computed, effect, httpResource, etc.)

Following this order makes Signal-based development more predictable. Running ng generate @angular/core:inject puts DI at the top of the component class, so many people may already write in this order.

As Signal-based development progresses, property order is not just style—it affects behavior.

See you next time.