DEV Community

Alfredo Perez
Alfredo Perez

Posted on

3 1

Where to initialize components selectors in Angular?

TL;DR

When using the selector in the component, it is recommended not to initialize them in the declaration and instead initialize them in the constructor.

export class FindBookPageComponent {
  searchQuery$: Observable<string>;
  books$: Observable<Book[]>;
  loading$: Observable<boolean>;
  error$: Observable<string>;

  constructor(private store: Store<fromBooks.State>) {
    this.searchQuery$ = store.pipe(
      select(fromBooks.selectSearchQuery),
      take(1)
    );
    this.books$ = store.pipe(select(fromBooks.selectSearchResults));
    this.loading$ = store.pipe(select(fromBooks.selectSearchLoading));
    this.error$ = store.pipe(select(fromBooks.selectSearchError));
  }

  search(query: string) {
    this.store.dispatch(FindBookPageActions.searchBooks({ query }));
  }
}
Enter fullscreen mode Exit fullscreen mode

Angular Type Safety

Initializing in the constructor helps because when using the strict mode in TypeScript, the compiler will not be able to know that the selectors were initialized on ngOnInit

The strictPropertyInitialization was added by default in the --strict mode in Angular 9.

The following checks where also added:

{
  "//": "tsconfig.json",
  "compilerOptions": {
    "noImplicitAny": true,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noFallthroughCasesInSwitch": true,
    "strictNullChecks": true
  }
}
Enter fullscreen mode Exit fullscreen mode

The strict-mode allows us to write much safe and robust application. Honestly, I think all Angular application should be written in strict-mode, but it is a little hard to understand every error messages caused by the compiler.


References

  • Angular 9 Strict Mode here
  • Angular Type safety here
  • Strict Property Initialization in TypeScript here

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More

Top comments (2)

Collapse
 
maxime1992 profile image
Maxime β€’

Instead of having one line for each declaration and another for assignment, I prefer to do all that at once. Here's how your example would look like:

export class FindBookPageComponent {
  searchQuery$: Observable<string> = this.store.pipe(
    select(fromBooks.selectSearchQuery),
    take(1)
  );
  books$: Observable<Book[]> = this.store.pipe(
    select(fromBooks.selectSearchResults)
  );
  loading$: Observable<boolean> = this.store.pipe(
    select(fromBooks.selectSearchLoading)
  );
  error$: Observable<string> = this.store.pipe(
    select(fromBooks.selectSearchError)
  );

  constructor(private store: Store<fromBooks.State>) {}

  search(query: string) {
    this.store.dispatch(FindBookPageActions.searchBooks({ query }));
  }
}
Collapse
 
layzee profile image
Lars Gyrup Brink Nielsen β€’ β€’ Edited

Nice tip. Did you consider initializing selectors in the properties?

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

πŸ‘‹ Kindness is contagious

Please leave a ❀️ or a friendly comment on this post if you found it helpful!

Okay