4

I am implementing Angular strict mode in a project where observables are heavily used in the controllers and templates. However, when discussing how we should initialize them, colleagues and I came up with a couple ways:

1.

public obj$: Observable<MyObj | null> = of(null)
public name$: Observable<string> = of('')
public arr$: Observable<Something[]> = of([])
public myObs$: Observable<Something> = NEVER
public name$: Observable<string> = NEVER
public arr$: Observable<Something[]> = NEVER

Which approach should we take, and why (or why not)?

Touhid Rahman
  • 533
  • 5
  • 14
  • FYI there also exists another solution albeit little inelegant since it works around the strict mode restriction: https://stackoverflow.com/a/50074076/6513921 – ruth Sep 20 '21 at 09:36
  • @MichaelD Our project is properly typed and we can count in fingers how many time we used `any`. So given that standard, throwing out the type checking with a `!` is an absolutely no-go. – Touhid Rahman Sep 20 '21 at 09:43
  • `EMPTY` would also be a possibility, no? I'd think it's preferable to `NEVER` because it's not good to have subscriptions that never complete. But I'm not sure – ShamPooSham Sep 20 '21 at 09:48

2 Answers2

1

IMO, it is a waste to create an object just to make typescript happy. Both EMPTY and NEVER will create an observable object.

I think I would prefer to use constructer. I know Angular used to have a guide line to use ngOnInit instead of the constructor, however, I think it is mainly to prevent something wrong related to presentation binding.

For initializing an Observable, I think it is totally fine to do it in constructor.

This has been discussed in Angular Github at https://github.com/angular/angular/issues/24571

I think this is what everyone will move to

quote from https://github.com/angular/angular/issues/24571#issuecomment-404606595

For angular components, use the following rules in deciding between:
a) adding initializer
b) make the field optional
c) leave the '!'

If the field is annotated with @input - Make the field optional b) or add an initializer a).
If the input is required for the component user - add an assertion in ngOnInit and apply c.
If the field is annotated @ViewChild, @ContentChild - Make the field optional b).
If the field is annotated with @ViewChildren or @ContentChildren - Add back '!' - c).
Fields that have an initializer, but it lives in ngOnInit. - Move the initializer to the constructor.
Fields that have an initializer, but it lives in ngOnInit and cannot be moved because it depends on other @input fields - Add back '!' - c).
maxisam
  • 21,975
  • 9
  • 75
  • 84
0

I like the simple of([]).

More info, see docs: https://www.learnrxjs.io/learn-rxjs/operators/creation/of

Melroy van den Berg
  • 2,697
  • 28
  • 31