javascript - Leder efter noget som OrElse i Angular RxJS find-funktion, mens der pipe's


Jeg har fået følgende stykke kode. Det, jeg prøver at opnå, er at omdirigere til siden ikke fundet, når "find"-funktionen ikke finder nogen ordreobjekt i de observerbare indlæste ordrer.

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())));
 });

Jeg har prøvet noget i stil med:

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']))
      ));
 });

Men det omdirigerer mig altid til siden ikke fundet-komponenten.

Svar #1

Du kan bruge tap-operatøren til at opnå det, du ønsker:

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']);
        }
      })
    ));

Du kan oprette et par brugerdefinerede rxjs-operatører for at slippe af med 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));
}

så kan din kode blive endnu enklere:

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

Svar #2

defaultIfEmpty() udløses faktisk kun, når observablen er fuldført, men intet returneres, https://www.learnrxjs.io/operators/conditional/defaultifempty.html det har intet at gøre med den returnerede værdi

Du kan prøve koden nedenfor

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()