I have this syntax:
const pageId = this._someService.currentData$<Data>().getValue().id;
which returns a normal string value with getValue()
from the Observable (BehaviourSubject) currentPage$<Page>()
. The class BehaviousSubject implements the getValue() method
export declare class BehaviorSubject<T> extends Subject<T> {
getValue(): T;
}
but how is that possible? I thought we have to subscribe to an observable to get the actual value.. ?
CodePudding user response:
private deviceType = new BehaviorSubject<string>('');
currentDeviceType = this.deviceType.asObservable();
changeDeviceType(value: string) {
this.deviceType.next(value);
}
This is how you can make a subject an Observable and the function to change the value, so now you can subscribe to the currentDeviceType and get all the value changes.
CodePudding user response:
There are multiple types of Observable
s, most of them do not hold the value, but some of them do.
The examples that hold values are BehaviorSubject
and ReplaySubject
.
BehaviorSubject
requires a value in the constructor. It implements all methods of Observable
as well as Subject
, but it has its own special value
and getValue
properties.
ReplaySubject
will reply X (provided in the constructor) number of the last emissions upon subscription. Passing 1
will make it almost into a BehaviorSubject
.
Why?
If you need some variable to be observable, but you sometimes need it immediately (synchronously), you make it into a BehaviorSubject
. You don't have to expose it as BehaviorSubject
, you could expose only the Observable
or Subject
of it.
class LoginService {
private readonly _isLoggiedIn$ = new BehaviorSubject(false);
public readonly isLoggiedIn$ = this._isLoggiedIn$ as Subject<boolean>;
}