Currently, I am working on implementing an observable for a validation task. There are 2 observables, frontEndValidate
and backEndValidate
, which I need to process sequentially in a specific order. If any of these observables throws an error, the entire pipeline should stop. These observables will be emitted at runtime when the user clicks on the validate
button by calling the next()
function inside the validate()
method.
Within the pipeline, I validate the emitted values from the observables. If the values are valid, the pipeline continues; otherwise, an error is thrown.
Currently, everything works as expected if both observables emit of({ valid: true})
. However, if either one emits of({valid:false})
, my validationAction$
stream stops functioning, and the validate
button becomes unresponsive.
The issue with using catchError
to handle errors is that it would not prevent the validation from continuing regardless of the state of the observables.
In summary, I want the pipeline to follow these rules and remain active:
- If both validations are successful: from([true,true])
- If one validation fails: from([true, false])
- If both validations fail: from([false])
Thank you for your help.
Pipeline
private validationSubject = new Subject<Observable<any>>();
validationAction$ = this.validationSubject.asObservable().pipe(
concatMap((item) =>
from(item)
.pipe(
map((result) => {
console.log("result", result);
if (!result.valid) throw new Error();
return result
}),
)
),
);
onClick
validate() {
this.validationSubject.next(this.frontEndValidate());
this.validationSubject.next(this.backEndValidate());
}
2 Observables
/* Front-end validation */
/** */
frontEndValidate(): Observable < any > {
// Validation goes here
return of({ valid: true, name: 'frontend', msg: 'Passed' }).pipe(
tap(() => {
console.log('frontend validation...starts');
}),
delay(3000), // mimic delay
tap(() => {
console.log('frontend validation...finished')
}),
);
}
/* Back-end validation */
/** */
backEndValidate(): Observable < any > {
// Validation goes here
return of({ valid: true, name: 'backend', msg: 'Passed' }).pipe(
tap(() => {
console.log('backend validation...starts');
}),
delay(3000), // mimic delay
tap(() => {
console.log('backend validation...finished')
}),
);
}