【问题标题】:Make an API call using switchMap based on a condition in typeahead of ng-bootstrap根据 ng-bootstrap 的预先输入条件使用 switchMap 进行 API 调用
【发布时间】:2021-05-23 16:05:44
【问题描述】:

我在我的 Angular 应用程序中使用 ng-bootstrap typeahead,并且希望仅在 typeahead 中搜索词的长度超过 3 个字符时才进行 API 调用以获取数据。我的组件中的代码是

search = (text$: Observable<string>) => {
  return text$.pipe(      
      debounceTime(200), 
      distinctUntilChanged(),
      switchMap((searchText) => {
          return this.carsService.getCars(searchText);
      }),
      map(response => {
          return response.cars.map((item: any) => {
            if(item.name === "Porsche") {
              item.name += " - Luxury car";
            }
            else {
              item.name += " - Normal car";
            }
            return item;
          });
      }),
      catchError(error => error)              
  );                 
 }

服务文件中调用API的代码是

getCars(searchText: string): Observable<any> {
  return this.http.get(`${environment.baseUrl}/cars?searchTerm=${searchText}`).pipe(
     map((res: any) => res),
     catchError(error => throwError(error))
  );
}

如何修改组件内部的代码,确保只有在用户输入的搜索词长度超过 3 个字符时才进行 API 调用,并确保返回空结果并且在 typeahead 中不显示任何内容如果搜索词的长度小于或等于 3 个字符,结果如何?请帮我解决这个问题。

【问题讨论】:

    标签: angular rxjs ng-bootstrap typeahead


    【解决方案1】:

    你可以在你的 switchMap 中做一个条件。 像这样:

    distinctUntilChanged(), 
    switchMap((searchText) => searchText.length > 3 ? this.carsService.getCars(searchText) : of({cars:[]}); 
    

    您可以从 rxjs 导入 of

    of

    【讨论】:

    • 我尝试了上述方法,方法是替换上面提到的 switchMap 中的代码并将逻辑保留在 map 运算符中,但是当我开始输入预输入时出现以下错误:你提供了一个无效的期望流的对象。您可以提供 Observable、Promise、Array 或 Iterable
    • 我认为 else 的情况应该是of({cars:[]})。否则它可能会失败,因为它在map 中找不到response.cars
    • 是的,它失败了,因为如果搜索词小于或等于 3 个字符,则响应是空数组。我在 map 中添加了一个 if 条件来解决这个问题: if(!response.cars) { return []; }。它现在完美运行。谢谢你:)
    • 我写得很快,感谢您的关注,我会编辑我的答案
    【解决方案2】:

    您可以将filter 运算符添加到您的信息流中

      return text$.pipe(      
          debounceTime(200), 
          distinctUntilChanged(),
         filter(val => val.length >= 3),
          switchMap((searchText) => {
              return this.carsService.getCars(searchText);
          }) ..... 
    

    【讨论】:

    • 如果搜索词少于或等于 3 个字符,过滤器不会清除结果,并且仍然显示以前的结果。根据我上面的评论,Ondie 的上述回答在地图运算符内部进行了轻微修改。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-17
    • 2017-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    相关资源
    最近更新 更多