I’m going to start by answering two questions you didn’t ask:
Should I use providedIn: "root"
?
No, because it makes it impossible to mock out the service for testing.
Should I expose my Subject
s as public service properties?
No, because it locks you into a particular implementation and leaks details of that implementation to clients. Make the Subject
private and expose it via a method like:
watchDeviceSpeed(): Observable<number> {
return this.deviceSpeed;
}
You sometimes see people use asObservable()
, but I think that’s pointless. Simply returning the Subject
as an Observable
will cause anybody trying to mess around in its guts to get build errors.
Now for the questions you did ask:
Is ngOnInit the right method in which subscribe the BehaviorSubject?
It’s a perfectly fine choice absent any specific considerations that would dictate otherwise.
Is unsubscribe mandatory?
“Mandatory” is a loaded word, but yes, you really want to unsubscribe, lest you leak subscriptions.
In which method should I unsubscribe the BehaviorSubject?
Whatever pairs with where you subscribed. If you subscribe in ngOnInit
, tear down in ngOnDestroy
.
One more bonus question you didn’t ask:
Do I have to do all this manually?
No. I use and recommend @ngneat/until-destroy, so all you have to do is this:
@UntilDestroy()
@Component(...)
export class Page {
constructor(private deviceManager: DeviceManager) {}
ngOnInit(): void {
this.deviceManager.watchDeviceSpeed().pipe(untilDestroyed(this))
.subscribe(speed => {...});
}
}