2017-07-30 38 views
2

我正在关注Angular教程来构建一个简单的应用程序。当我在输入框中输入术语时,应用程序会发送一个Ajax来搜索用户。我在这里与Observable混淆。Angular Observable错误处理

(1)如果搜索词短于3个单词,我想清除数据。我使用Observable.of来返回一个空数组。

(2)如果发生http错误,一个空数组也会在catch块中返回。

然而,在这两种情况之一后,似乎流'停止',因为我指向this.users到一个新的Observable。我是否应该再次执行类似this.users = new Subject()的操作?在这里做什么正确的方法?

HTML:

<div class="wrapper"> 
    <input #searchBox id="search-box" (keyup)="search(searchBox.value)" /> 
    <div class="loader" [hidden]="!loading"></div> 
</div> 

getUserService:

//Sending ajax, return an Observable 

组件:在正确的地方

export class searchComponent implements OnInit { 

    constructor(private getUserService: GetUserService) { } 

    private searchTerms = new Subject<string>(); 

    users: Observable<User[]>; 
    loading: boolean = false; 

    search(term: string): void { 
     if(term.length >= 3) { 
      this.loading = true; 
      this.searchTerms.next(term); 
     } else { 

      //issue (1) occurs after this 

      this.users = Observable.of<User[]>([]); 
     } 
    } 

    ngOnInit(): void { 
    this.users = this.searchTerms 
     .debounceTime(400) 
     .distinctUntilChanged() 
     //service will not be called after (1) or (2) occurs 
     .switchMap(term => this.getUserService.getUser(term)) 
      .map(data => { 
       this.loading = false; 
       return data; 
      }) 
     .catch(error => { 

     //issue (2) occurs after this 

     this.loading = false; 
     return Observable.of<User[]>([]); 
     }); 
    } 
} 

回答

3

你没有做的事情。它应该是

search(term: string) { 
    // emit systematically. The observable chain will just return 
    // 0 result if the term is too short 
    this.searchTerms.next(term); 
} 

ngOnInit() { 
    this.users = this.searchTerms 
     .debounceTime(400) 
     .distinctUntilChanged() 
     .switchMap(term => { 
     if (term.length < 3) { 
      return Observable.of([]); 
     } 
     else { 
      this.loading = true; 
      return this.getUserService.getUser(term) 
        // catch here to make sure that an http error doesn't break the chain 
        .catch(() => return Observable.of([]) 
        .finally(() => this.loading = false); 
     } 
     }); 
}