Reputation: 2337
I am using Angular 2 RC-4. I am trying to make a network request whenever there is a change in the input box. But the request is getting called twice.
My code looks like:
component.ts
this.term = new Control();
this.suggestions = this.term.valueChanges
// .debounceTime(1000)
// check if the search term's length is >= 1
.filter(term => term && term.length)
// switchMap only subscribes to one observable at a time so if a new key is
// pressed before the response of previous request has been recieved, it
// automatically un-subscribes from the previous observable thus cancelling the previous
// request.
.switchMap(term => this._suggestionsService.getSuggestions(term, uuid))
component.html
<ul [hidden]='!(suggestions | async)?.length'>
<li *ngFor='let suggestion of suggestions | async'>{{suggestion.name}}</li>
</ul>
suggestion.service.ts
getSuggestions(term){
return this.http.get('some-url')
.map((res: Response) => res.json());
}
This makes the network request 2 times. But if I change the code in component slightly and manually subscribe instead of using async pipe, the network request is only made once.
component.ts
this.term.valueChanges
.filter(term => term && term.length)
.switchMap(term => this._suggestionsService.getSuggestions(term, uuid))
.subscribe(value => this.suggestions = value);
component.html
<ul [hidden]='!suggestions.length'>
<li *ngFor='let suggestion of suggestions'>{{suggestion.name}}</li>
</ul>
Results are fine in both. Only the number of network requests is my concern. I guess there is some concept about observables that I am missing.
Upvotes: 7
Views: 9539
Reputation: 16718
The problem is that there are 2 async
in the template that causes the observable to be subscribed multiple times and hence the request is made 2 times.
Using share
will do the trick:
this.suggestions = this.term.valueChanges
.filter(term => term && term.length)
.switchMap(term => this._suggestionsService.getSuggestions(term, uuid))
.share();
Upvotes: 14