Как и предполагалось, конвейер filter
выполняет свою работу, но вы явно не хотите иметь условное выражение, которое можно понять с точки зрения многословия.Это не очень красиво, правда?
filter(data => data !== undefined)
filter(data => !!data)
Есть два решения, чтобы избежать !==
или сокращения !!data
.
Во-первых, вы можете использовать Boolean
конструктор.Это функция с сигнатурой (any) => boolean
, поэтому вы можете сделать это:
filter(Boolean)
Будьте осторожны, хотя значения ложных значений (false, "", 0) также будут фильтроваться таким образом.Это только сохранить для использования с object
.
Еще лучше и многократно используется создание собственного оператора, который будет выглядеть следующим образом:
function filterEmpty<T>(): MonoTypeOperatorFunction<T> {
return (source: Observable<T>) => source.pipe(filter(val => val != undefined));
}
Затем вы можете использовать его в своем примере кода:
this.someStream$
.pipe(filterEmpty())
.subscribe((data: any[]) => {
this.someVar = data.map(item => new SomeModel(item ));
});
ТИПЫ
Есть еще одна проблема с этим подходом, и это типы.
Представьте себе:
class X {
public a;
}
let x: X | undefined = undefined;
of(x)
.pipe(filter(y => !!y))
.subscribe(y => {
let i = y.a;
});
Мы получимошибка типа при назначении i
, так как y
равно X | undefined
.Очень неудачно.
Но с этим типизированным оператором мы можем преобразовать X | undefined
в X
:
export function filterNullable<T>(): OperatorFunction<T | undefined, T> {
return (source: Observable<T | undefined>) => source.pipe(
filter<T | undefined, T>(
function (val: T | undefined): val is T {
return val !== undefined;
}));
}
Очень удобно.