Как сделать что-то в подписке Rx только после допустимого значения? - PullRequest
0 голосов
/ 24 сентября 2018

Как сделать что-то в подписке Rx только после действительного значения?

Например, я получаю 'null', 'null' и только после этого массива с данными

Например:

this.someStream$.subscribe((data: any[]) => {
  if (data) {
    this.someVar= data.map(item => new SomeModel(item ));
});

Как избежать "if (data) {}"

Ответы [ 2 ]

0 голосов
/ 24 сентября 2018

Как и предполагалось, конвейер 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;
            }));
}

Очень удобно.

0 голосов
/ 24 сентября 2018

Вы можете использовать filter для этой цели:

this.someStream$
  .filter(data => data !== null || typeof data != "undefined")
  .subscribe((data: any[]) => {
    this.someVar = data.map(item => new SomeModel(item));
  });
...