Reputation: 10324
Even though I've defined a type guard filter, I can't seem to get rid of my null
observables. I defined my type guard:
export const hasValue = <T>(value: T): value is NonNullable<T> => value !== null && value !== undefined
and then my methods that want to filter like so:
#validateDocument(document: IDocument): Observable<AcmsDocumentBad | null> { ... }
validateDocuments(documents: IDocument[]): Observable<AcmsDocumentBad[]> {
const observables = documents
.filter(x => x.approvedSor === 'ACMS')
.map(this.#validateDocument)
return forkJoin(observables)
.pipe(filter(hasValue))
}
I had expected that uses the pipe like that would result in Observable<AcmsDocumentBad[]>
as the type, but it's still showing as Observable<(AcmsDocumentBad | null)[]>
Upvotes: 0
Views: 750
Reputation: 3399
forkJoin(Array<Observable<AcmsDocumentBad | null>>)
returns an Observable<Array<AcmsDocumentBad | null>>
, which emits an array with all the results just once, when all of the inner observables have completed.
If you do .pipe(filter(hasValue))
on this, the result will be the same, because the observable never emits nulls, it will emit just one Array, guaranteed. The inner values of that array could be null though.
You probably want to just do .pipe(map(array => array.filter(hasValue)))
Or if you don't fancy array methods, .pipe(switchAll(), filter(hasValue), toArray())
(i.e. flattening the Observable<Array<T>>
to Observable<T>
, filtering, then recreating the array with the values filtered.
Upvotes: 1