Angular如何避免错误打破valueChanges

时间:2018-11-15 13:51:01

标签: angular rxjs

在我的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。 我需要处理组件中的错误,而不是服务中的错误。

3 个答案:

答案 0 :(得分:3)

您在valueChanges属性上的rxjs语句产生的可观察结果已已完成,这就是为什么它不再起作用的原因了。

重要提示:可以观察到的错误将被完成,并且您无能够改变这种行为。

您需要做的是防止来自端点服务的错误流到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

答案 1 :(得分:0)

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

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

答案 2 :(得分:-2)

此方法可能解决了我的问题,这是组件,而服务什么也没捕获:

[19:40:00] (node:7766) UnhandledPromiseRejectionWarning: Error: jest-haste-map: @providesModule naming collision:
[19:40:00]   Duplicate module name: react-native-cli
[19:40:00]   Paths: /home/Desktop/projects/app/storybook/node_modules/react-native/react-native-cli/package.json collides with 
/home/Desktop/projects/app/vendor-mobile/node_modules/react-native/react-native-cli/package.json
[19:40:00] 
[19:40:00] This error is caused by a @providesModule declaration with the same name across two different files.
[19:40:00]     at setModule (/home/Desktop/projects/app/vendor-mobile/node_modules/jest-haste-map/build/index.js:462:17)
[19:40:00]     at workerReply (/home/Desktop/projects/app/vendor-mobile/node_modules/jest-haste-map/build/index.js:512:9)
[19:40:00]     at <anonymous>
[19:40:00]     at process._tickCallback (internal/process/next_tick.js:188:7)
..............
..............