I need to get current value and invert it:
public controlActive$ = new ReplaySubject<Tool>();
if(this.type == "A") {
this.controlActive$.next(!controlActive$.getValue());
}
How to do that more elegant?
Is this only needed in the initialization? if so, you could use a BehaviorSubject instead:
public controlActive$: BehaviorSubject<boolean>;
public constructor(private type: string) {
this.controlActive$ = new BehaviorSubject<boolean>(this.type === 'A');
}
the initial value would be true
then, if type === 'A'.
To toggle it, your method could then be applied:
public toggle() {
this.controlActive$.next(!this.controlActive$.getValue());
}
ReplaySubject
does not have contain getValue()
function or a .value
getter. For that you'd need to use the BehaviorSubject
that accepts a default value.
private controlActiveSource: BehaviorSubject<Tool> = new BehaviorSubject<Tool>(null); // <-- needs a default value
public controlActive$: Observable<Tool> = this.controlActiveSource.asObservable();
if (this.type == "A") {
this.controlActive$.next(!this.controlActive$.getValue());
}
The topic of "elegance" is subjective. Some would say (including the core lead of RxJS) using the getValue()
is inelegant and an anti-pattern since it allows synchronous access to the value.
In that case you could decouple the current state from the multi-cast observable.
private controlActive: boolean = false;
private controlActiveSource: ReplaySubject<Tool> = new ReplaySubject<<Tool>(1);
public controlActive$: Observable<Tool> = this.controlActiveSource.asObservable();
if (this.type == "A") {
this.toggleControl();
this.controlActive$.next(this.controlActive);
}
toggleControl() {
this.controlActive = !this.controlActive;
}
Using BehaviorSubject.getValue()
is discouraged in general (see this comment). Instead you should subscribe to the Subject even though it's not a very elegant solution:
this.controlActive$
.pipe(
take(1),
)
.subscribe(value => this.controlActive$.next(!value));