I have the following RXJS streams:
this.widthBorder$.pipe(skip(1)).subscribe((value) => {
this.registryBoundaries.setAttribute('stroke-width', `${value || 0}`);
});
this.widthBorderColor$.pipe(skip(1)).subscribe((value) => {
this.registryBoundaries.setAttribute('stroke', `${value || 0}`);
});
this.drawContour$.pipe(skip(1)).subscribe((value) => {
this.registryBoundaries.style.display = value ? 'block' : 'none';
});
As you can see there are a duplicates of code like skip(1)
also there methods are the similar?
I skip first value because all streams are BehaviorSubject
.
How to optimize it?
CodePudding user response:
It seems that you should use Subject
instead of BehaviorSubject
for this case. Subject will emit no initial value upon subscription and this will save you the need to use the skip
operator.
For reading from multiple observables, there is no magic solution. You may use a thing like zip
so you have an array of emitted values of the observables (but you will have to pipe each observable with startWith(null) so they emit a value, since zip will only emit once all observables have emitted). You may also use merge
to simply fuse all observables into a single observable, but you won't be able to tell which observable has emitted the received value unless you add some sort of tag.
I think your implementation is fine once you switch from BehaviorSubject
to Subject
and remove all the skip operators. If you had ten more subscriptions like this, I would suggest creating the observables programatically, but for three subscriptions nothing will save you much lines of code.
CodePudding user response:
just use Subject
instead of BehaviorSubject
BehaviourSubject
BehaviourSubject will return the initial value or the current value on Subscription
Subject
Subject does not return the current value on Subscription. It triggers only on .next(value) call and return/output the value
public widthBorder$ = new Subject();
public widthBorderColor$ = new Subject();
public rawContour$ = new Subject();
this.widthBorder$.subscribe(v => this.setAttribute('stroke', `${v || 0}`));
this.widthBorderColor$.subscribe(v => this.setAttribute('stroke-width', `${v || 0}`));
this.drawContour$.subscribe((value) => {
this.registryBoundaries.style.display = value ? 'block' : 'none';
});
public setAttribute(attr: string, value: string): void {
this.registryBoundaries.setAttribute(attr, value);
}