You can also make an Angular pipe that works directly with Observables. Then your filtering pipe could operate on either Observables or 'hard values'.
But when it's using an observable - you'll never get an error because the code won't run until there is a value.
To do this, in the signature (note the any is an array) put:
transform(value: Observable<any> | any[])
and then check inside for either an observable or a 'hard value':
@Pipe({ name: 'filterLectures' })
export class FilterLecturesPipe implements PipeTransform {
constructor() {}
transform(value: Observable<any> | Array<any>, filterValue: any): Observable<any> | Array<any>
{
if (isObservable(value))
{
return value.pipe(filter(v => filterLecturesFunction(filterValue, v) ));
}
else
{
return (value as Array<any>).filter(v => filterLecturesFunction(filterValue, v) );
}
}
}
Then you use it like this - nice and clean:
However this is probably bad practice, because pipes shouldn't really know much about your data model. Better to filter in the client and expose various observables.
Another way is to make a generic 'startWith' pipe with a default:
@Pipe({ name: 'startWith' })
export class StartWithPipe implements PipeTransform {
constructor() {}
transform(value: Observable<any> | any, defaultValue: any): Observable<any> {
if (isObservable(value)) {
return value.pipe(startWith(defaultValue));
} else {
throw Error('Needs to be an observable');
}
}
}
This only works with observables so you have to put it before the async:
I'm not sure of the official guidance regarding pipes using observables OR values, but this is what I've done if I need something to work with either an observable or an actual value.