Ищите что-то похожее на OrElse в угловых функциях поиска rxjs во время трубопровода - PullRequest
1 голос
/ 04 ноября 2019

У меня есть следующий кусок кода. Я пытаюсь добиться перенаправления на страницу, которая не найдена, когда функция «найти» не находит какой-либо объект заказа в наблюдаемых загруженных заказах.

private order: Observable<OrderModel>;

ngOnInit() {
    this.route.params.subscribe(params => {
    this.name = params.id;
    this.order = this.orderService.ordersLoaded.pipe(map((orders: OrderModel[]) => orders
          .find((order: OrderModel) => order.orderName === this.name.toUpperCase())));
 });

Я пробовал что-то вроде:

ngOnInit() {
    this.route.params.subscribe(params => {
    this.name = params.id;
    this.order = this.orderService.ordersLoaded.pipe(map((orders: OrderModel[]) => orders
        .find((order: OrderModel) => order.orderName === this.name.toUpperCase()),
        defaultIfEmpty(this.router.navigate(['/notFound']))
      ));
 });

Но он всегда перенаправляет меня на страницу не найденный компонент.

Ответы [ 2 ]

0 голосов
/ 04 ноября 2019

defaultIfEmpty() фактически срабатывает, только когда наблюдаемое завершено, но ничего не возвращено, https://www.learnrxjs.io/operators/conditional/defaultifempty.html это не имеет никакого отношения к возвращенному значению

Вы можете попробовать код ниже

zip(this.orderService.ordersLoaded,this.route.params).pipe(tap([orders,params])=>{
  this.name = params.id;
  if(!orders.find(order=>order.orderName === this.name.toUpperCase())
        this.router.navigate(['/notFound'])
}).subscribe()
0 голосов
/ 04 ноября 2019

Вы можете нажать оператора, чтобы заархивировать то, что вы хотите:

this.order = this.orderService.ordersLoaded.pipe(
      map((orders: OrderModel[]) => orders.find(order => order.orderName === this.name.toUpperCase()),
      tap(order => {
        if (!order) {
          this.router.navigate(['/notFound']);
        }
      })
    ));

Вы можете создать несколько пользовательских операторов rxjs, чтобы избавиться от if:

export function tapIf<T>(
  predicate: (value: T) => boolean,
  fn: (x: T) => void
): MonoTypeOperatorFunction<T> {
  return input$ =>
    input$.pipe(
      tap(x => {
        if (predicate(x)) {
          fn(x);
        }
      })
    );
}

export function tapIfFalsy<T>(fn: (x: T) => void): MonoTypeOperatorFunction<T> {
  return tapIf<T>(x => !x, x => fn(x));
}

, затем выкод может стать еще проще:

this.order = this.orderService.ordersLoaded.pipe(
      map((orders: OrderModel[]) => orders.find(order => order.orderName === this.name.toUpperCase()),
      tapIfFalsy(() => this.router.navigate(['/notFound']))
    ));
...