I have the following four listeners:
this.reportPropertiesChanges$.pipe(filter(() => this.loaded)).subscribe((v) => {
this.registryReportSettings.reportProperties = v;
this.registryReportSettings$.next(this.registryReportSettings);
});
this.objectsProperties$.pipe(filter(() => this.loaded)).subscribe((v) => {
this.registryReportSettings.reportObjectsProperties = v;
this.registryReportSettings$.next(this.registryReportSettings);
});
this.textPropertiesChanges$.pipe(filter(() => this.loaded)).subscribe((v) => {
this.registryReportSettings.textProperties = v;
this.registryReportSettings$.next(this.registryReportSettings);
});
this.toggleLabels$.pipe(filter(() => this.loaded)).subscribe((v) => {
this.registryReportSettings.visibleText = v;
this.registryReportSettings$.next(this.registryReportSettings);
});
How to combine them to one operator? I can not use combineLatest because not all streams can be launched.
CodePudding user response:
I would refactor it smth like:
import { merge } from 'rxjs';
import { map } from 'rxjs/operators';
...
const forwardProp = prop => value => ({prop, value});
const obs = [
this.reportPropertiesChanges$.pipe(map(forwardProp('reportProperties'))),
this.objectsProperties$.pipe(map(forwardProp('reportObjectsProperties'))),
this.textPropertiesChanges$.pipe(map(forwardProp('textProperties'))),
this.toggleLabels$.pipe(map(forwardProp('visibleText')))
];
merge(...obs).pipe(filter(() => this.loaded)).subscribe(({prop, value}) => {
this.registryReportSettings[prop] = value;
this.registryReportSettings$.next(this.registryReportSettings);
});
CodePudding user response:
You can use merge, which will trigger if any Observable will emit a value
this.reportPropertiesChanges$.pipe(map(reportProperties => ({reportProperties})));
this.objectsProperties$.pipe(map(reportObjectsProperties => ({reportObjectsProperties})));
this.textPropertiesChanges$.pipe(map(textProperties => ({textProperties})))
this.toggleLabels$.pipe(map(visibleText => ({visibleText})));
merge(
this.reportPropertiesChanges$,
this.objectsProperties$,
this.textPropertiesChanges$,
this.toggleLabels$
)
.pipe(
filter(() => this.loaded)
).subscribe((p) => {
this.registryReportSettings = {...this.registryReportSettings, ...p };
this.registryReportSettings$.next(this.registryReportSettings);
});
CodePudding user response:
You can use combineLatest operator from rxjs as well. It will give you access to all the 4 subscribables in one operator. Something like this:
const reportProps = this.reportPropertiesChanges$;
const objectsProperties = this. objectsProperties$;
const textPropertiesChanges = this.textPropertiesChanges$;
const toggleLabels = this. toggleLabels$;
combineLatest([
reportProps,
objectsProperties,
textPropertiesChanges,
toggleLabels
]).pipe(filter(() => this.loaded)).subscribe(([
reportPropsValue,
objPropsValue,
textChangesValue,
toggleLabelsValue
]) => {
this.registryReportSettings.reportProperties = reportPropsValue;
this.registryReportSettings.reportObjectsProperties = objPropsValue;
this.registryReportSettings.textProperties = textChangesValue;
this.registryReportSettings.visibleText = toggleLabelsValue;
// Once you set all the values, you can update the Behavior Subject
this.registryReportSettings$.next(this.registryReportSettings);
})