Search code examples
angularobservableangular5rxjs5

Angular - Catch error in component


i'm making an app in Angular (5), and i'm not very practice with Subject. I want catch the Observable error in my component, but i can't do. This is my code

My model: example-model.ts

export class ExampleModel { 
    public value: string; 
}

My Service: example-model-service

@Injectable()
export class ExampleModelService implements OnDestroy{

  destroy$: Subject<boolean> = new Subject<boolean>();
  private exampleModel$ = new ReplaySubject<ExampleModel>(1);

  constructor() { }

  exampleModelInit(){
    //Observable.from([{'value': 'Hello World'}])
    Observable.create(sub => sub.error('Observable Error'))
      .pipe(
        distinctUntilChanged(),
        takeUntil(this.destroy$)
      )
      .subscribe((exampleModel: ExampleModel) => {
        this.sendExampleModel(exampleModel);
      },
        err => this._handleError(err));
  }

  private _handleError(err: any) {
    return Observable.throw(err);
  }

  private sendExampleModel(exampleModel: ExampleModel) {
    this.exampleModel$.next(exampleModel);
  }

  public whenExampleModel(): Observable<ExampleModel> {
    this.exampleModelInit();
    return this.exampleModel$.asObservable();
  }

  ngOnDestroy() {
    this.destroy$.next(true);
    this.destroy$.unsubscribe();
  }
}

My Component: home-component.ts

export class HomeComponent implements OnInit, OnDestroy {

  public exampleModel$: Observable<ExampleModel>;

  public unsubscribe$: Subject<boolean> = new Subject<boolean>();

  controls: boolean = false;
  indicators: boolean = false;

  constructor(private exampleModelService$: ExampleModelService) {
  }

  ngOnInit() {
  }

  getExampleModel() {
    this.exampleModel$ = this.exampleModelService$.whenExampleModel();

  }

  ngOnDestroy(): void {
    this.unsubscribe$.next(true);
    this.unsubscribe$.unsubscribe();
  }

}

I want catch my error in getExampleModel(), i tried with .catch with no result.

Thanks


Solution

  • First problem is you are using a asynchronous method as a normal method that return a value when is executed.

    Then, the first change that we need to make is move logic for catch error in this.exampleModelService$.whenExampleModel(); method.

    The whenExampleModel() method must return an observable to the consumer for can obtaing asynchronus result. An asynchronus result is a result that will come in the future but not is available

    Try to change this

        @Injectable()
    export class ExampleModelService implements OnDestroy{
    
      destroy$: Subject<boolean> = new Subject<boolean>();
      private exampleModel$ = new ReplaySubject<ExampleModel>(1);
      private obs : Observable<ExampleModel>;
    
      constructor() { }
    
      exampleModelInit(){
        //Observable.from([{'value': 'Hello World'}])
        this.obs = Observable.create(sub => sub.error('Observable Error'))
          .pipe(
            distinctUntilChanged(),
            takeUntil(this.destroy$)
          );
      }
    
      private _handleError(err: any) {
        return Observable.throw(err);
      }
    
      private sendExampleModel(exampleModel: ExampleModel) {
        this.exampleModel$.next(exampleModel);
      }
    
      public whenExampleModel(): Observable<ExampleModel> {
        this.exampleModelInit();
        return this.obs;
      }
    
      ngOnDestroy() {
        this.destroy$.next(true);
        this.destroy$.unsubscribe();
      }
    }
    

    Component

    whenExampleModel.subscribe(s=>{},e=>{});