繁体   English   中英

Angular 如何避免错误破坏 valueChanges

[英]Angular how to avoid that errors break valueChanges

在我的 angular 6 应用程序中,我遇到了一些 rxjs 操作符的问题。 我有一个搜索字段,当用户在该字段中输入时,我需要调用我的服务(服务执行 GET 请求),如果该服务没有任何错误(如 500),它就可以工作。

但是 500 错误的请求破坏了值更改的链,可能我没有从服务中返回正确的值...

这是组件中的搜索字段:

this.manufacturer.valueChanges
  .pipe(
    filter((value: string) => (value ? value.length > 2 : false)),
    tap(() => (this.loadingAutocomplete = true)),
    debounceTime(500),
    switchMap(val => this.frameService.getItems(val, "manufacturerAutocomplete")),
    tap(() => (this.loadingAutocomplete = false)),
    catchError(err =>
      return of([]))
  )
  .subscribe(
    manufacturers => {
      this.matchingManufacturers.next(manufacturers);
    },
    err => {
      this.loadingAutocomplete = false;
      this.matchingManufacturers.next([]);
    }
  );

这是服务:

getItems(value: string, endPoint: string) {
  return this.http.get(
    this.endPointUrlService.cutLinks(this.endPointUrlService.map.get("frames")) + "/search/" + endPoint
  ).pipe(
    map((res: string[]) => {
      if (res) {
        return res;
      } else {
        return [];
      }
    })
  );
}

第一次用户输入一些它有效的东西,如果我有一个错误,则不会再次调用 valueChanges。 我需要处理组件中的错误,而不是服务中的错误。

由您对 valueChanges 属性的 rxjs 语句产生的 observable 已完成,这就是它不再反应的原因。

重要提示:一个可观察到的错误,将完成,并且您无法改变该行为。

您需要做的是防止端点服务的错误向下流入 switchMap 语句,并进一步流入链中。 如果它流入链条,则该链条将完成。 为了防止错误向下流,您需要在 api 调用抛出错误时返回 empty()。

getItems(value: string, endPoint: string) {
    return this.http.get(this.endPointUrlService.cutLinks(this.endPointUrlService.map.get("frames")) + "/search/" + endPoint).pipe(
      map((res: string[]) => {
        if (res) {
          return res;
        } else {
          return [];
        }
      }),
      catchError(err => {
          // report error to user
          console.log(err);
          // Important: stop observable from emitting anything
          return empty();
      })
    );
}

有关该主题的更多信息:http ://www.syntaxsuccess.com/viewarticle/error-handling-in-rxjs

更早地捕获错误 - 在服务层中,如下所示:

 getItems(value: string, endPoint: string) {
        return this.http.get(this.endPointUrlService.cutLinks(this.endPointUrlService.map.get("frames")) + "/search/" + endPoint).pipe(
          map((res: string[]) => {
            if (res) {
              return res;
            } else {
              return [];
            }
          }),
          catchError(err => return of([]))
    );
  }

可能这个方法解决了我的问题,这是组件,服务没有捕获任何东西:

this.manufacturer.valueChanges
  .pipe(
    filter((value: string) => (value ? value.length > 0 : false)),
    tap(() => (this.loadingAutocomplete = true)),
    debounceTime(500),
    switchMap(val =>
      this.frameService.getItems(val, "manufacturerAutocomplete").pipe(
        catchError(err => {
          handleError(err);
          this.loadingAutocomplete = false;
          return [];
        })
      )
    ),
    tap(() => (this.loadingAutocomplete = false))
  )
  .subscribe(
    manufacturers => {
      this.matchingManufacturers.next(manufacturers);
    },
    err => {
      this.loadingAutocomplete = false;
      this.matchingManufacturers.next([]);
    }
  );

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM