concatMap observables, go to next on error, stop when one completes #7526
-
| 
         I was surprised that it didn't seem very easy to do what I was trying to accomplish. I was able to get close enough in a very ugly way (please don't ask me to share 😳). 
 I looked at the  Is there some easy way to do what I want? I know this is prolly pretty weird, but mumble mumble.  | 
  
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
| 
         Did you want to get something like this? // the function is just for example
export function ofError<T>(...values: T[]): Observable<T> {
  return concat(
    from(values),
    throwError(() => new Error())
  );
}
of(
  ofError('a', 'b', 'c'), // log a b c
  ofError('e', 'f', 'g'), // log e f g
  of('h', 'i', 'g'), // log h i g & complete
  ofError('k', 'j', 'm'), // ignore
)
  .pipe(
    concatMap((item$) => item$.pipe(materialize())),
    takeWhile(({ kind }) => kind !== 'C'),
    filter(({ kind }) => kind !== 'E'),
    dematerialize()
  )
  .subscribe((value) => {
    console.log(value);
  });You can wrap it in something like: function concatMapError<I, O>(
  project: (value: I) => Observable<O>
): OperatorFunction<I, O> {
  return pipe(
    concatMap((item) => project(item).pipe(materialize())),
    takeWhile(({ kind }) => kind !== 'C'),
    filter(({ kind }) => kind !== 'E'),
    dematerialize()
  );
}or function concatMapError<T, O extends ObservableInput<unknown>>(
  project: (value: T) => O
): OperatorFunction<T, ObservedValueOf<O>> {
  return pipe(
    concatMap((item) => from(project(item)).pipe(materialize())),
    takeWhile(({ kind }) => kind !== 'C'),
    filter(({ kind }) => kind !== 'E'),
    dematerialize()
  );
} | 
  
Beta Was this translation helpful? Give feedback.
I can also suggest this solution:
But in my opinion
materializeanddematerializeare much clearer.You can always make a completely custom operator that will fully satisfy your specific requirements.