Is there a way to combine the subscriptions for this.controls.attendanceDate and this.controls.type? I need to have access to both at the same time in order to call each of this.isAttendanceDateOnOrAfterStartDate() and this.isAttendanceDuplicate() at the same time in the if statement.
onAttendanceFormChanges(): void {
this.subscriptions.push(this.controls.attendanceDate.valueChanges.subscribe(() => {
this.subscriptions.push(this.$spService.clientProfile$.subscribe(client => {
if (this.controls.attendanceDate.value) {
if (this.isAttendanceDateOnOrAfterStartDate(this.controls.attendanceDate.value, client)) {
this.isValidAttendanceDate$.next(false);
this.controls.attendanceDate.setErrors(null);
this.controls.status.enable();
} else {
this.isValidAttendanceDate$.next(true);
this.controls.attendanceDate.setErrors({ 'duplicate': true });
this.controls.status.disable();
}
}
}));
}));
this.subscriptions.push(this.controls.type.valueChanges.subscribe(() => {
this.subscriptions.push(this.$spService.clientAttendance$.subscribe(attendances => {
if (this.controls.attendanceDate.value) {
if (this.isAttendanceDuplicate(this.controls.attendanceDate.value, this.controls.type.value.id, attendances)) {
this.isDuplicateAttendance$.next(true);
this.controls.attendanceDate.setErrors({ 'duplicate': true });
this.controls.status.disable();
} else {
this.isDuplicateAttendance$.next(false);
this.controls.attendanceDate.setErrors(null);
this.controls.status.enable();
}
}
}));
}));
CodePudding user response:
Use merge
operator to combine multiple subscriptions. See the example https://www.learnrxjs.io/learn-rxjs/operators/combination/merge
merge(this.controls.attendanceDate.valueChanges, this.controls.type.valueChanges)
.subscribe((data) => {
// Do your stuff here
});
CodePudding user response:
Avoid subscribing inside subscribe. Use composability of rxjs to avoid subscription inside subscription. You can rewrite your observables like this -
onAttendanceFormChanges(): void {
const attendanceDateValueChanges$ =
this.controls.attendanceDate.valueChanges.pipe(
mergeMap(() => {
return this.$spService.clientProfile$;
}),
tap(client => {
if (this.controls.attendanceDate.value) {
if (this.isAttendanceDateOnOrAfterStartDate(this.controls.attendanceDate.value, client)) {
this.isValidAttendanceDate$.next(false);
this.controls.attendanceDate.setErrors(null);
this.controls.status.enable();
} else {
this.isValidAttendanceDate$.next(true);
this.controls.attendanceDate.setErrors({ 'duplicate': true });
this.controls.status.disable();
}
}
})
)
const typeValueChanges$ =
this.controls.type.valueChanges.pipe(
mergeMap(() => {
return this.$spService.clientAttendance$;
}),
tap((attendances) => {
if (this.controls.attendanceDate.value) {
if (this.isAttendanceDuplicate(this.controls.attendanceDate.value, this.controls.type.value.id, attendances)) {
this.isDuplicateAttendance$.next(true);
this.controls.attendanceDate.setErrors({ 'duplicate': true });
this.controls.status.disable();
} else {
this.isDuplicateAttendance$.next(false);
this.controls.attendanceDate.setErrors(null);
this.controls.status.enable();
}
}
})
);
merge(attendanceDateValueChanges$, typeValueChanges$).subscribe();
}));
Since you have not posted much details about 'what is your meaning by combine' - So I have used merge
operator. You could also use combineLatest
OR zip
depends on what your need is. Google about these operators to combine your observables.
Hope it helps.