Search code examples
angularrxjsangular8rxjs-pipeable-operators

How to handle error rxjs using operator from?


In ngOnChanges I listen Input data to component.

ngOnChanges(): void {
    from(this.zuPrimaryData).pipe(
      max((a, b) => a["nu"] - b["n"])
    ).subscribe((data) => {
      console.log(data);
    });
  }

First time this.zuPrimaryData comes as null ir arises error, thus ngChanges works.

How to handle this and dont create stream if null?

This code is not get me data in template:

  ngOnChanges(): void {
    this.zu$ = iif(() => this.data, from(this.data)).pipe(
      max((a, b) => a["n"] - b["n"]),
      map((data) => data)
    );
  }

Template is:

{{zu$ | async }}

Solution

  • If you need a pure RxJS solution, you could use iif conditional function. Try the following

    ngOnChanges(): void {
      iif(() => this.zuPrimaryData, from(this.zuPrimaryData)).pipe(
        max((a, b) => a["nu"] - b["n"])
      ).subscribe((data) => {
        console.log(data);
      });
    }
    

    Here the observable is created only if the zuPrimaryData is defined. If the condition is false, it returns RxJS EMPTY constant.

    From EMPTY docs:

    Creates an Observable that emits no items to the Observer and immediately emits a complete notification.

    You could also make the condition more explicit for readability: iif(() => (this.zuPrimaryData && this.zuPrimaryData !== null), from(this.zuPrimaryData))


    Update: to use async pipe

    To use the async pipe you need to remove the subscription from the controller.

    Option 1: using async pipe

    Controller

    result$: any;
    
    ngOnChanges(): void {
      this.result$ = iif(() => this.zuPrimaryData, from(this.zuPrimaryData))
        .pipe(max((a, b) => a["nu"] - b["n"]));
    }
    

    Template

    <div>{{ result$ | async }}</div>
    

    Option 2: using subscription (without async pipe)

    Controller

    result: any;
    
    ngOnChanges(): void {
      iif(() => this.zuPrimaryData, from(this.zuPrimaryData))
        .pipe(max((a, b) => a["nu"] - b["n"]))
        .subscribe(data => this.result = data);
    }
    

    Template

    <div>{{ result }}</div>