Reputation: 3680
I don't exactly know what is going wrong but I'm trying to apply the search system from the angular doc with no success.
Here are the function used in the component :
// my-comp.component.ts
public testing: Observable<any>;
private searchTerms = new Subject<string>();
search(term: string): void {
this.searchTerms.next(term.toUpperCase());
}
This function is hit each time I type something in the searchbox so no problem here.
Here is the ngOnInit method :
// my-comp.component.ts
ngOnInit(): void {
this.testing = this.searchTerms
.debounceTime(300) // wait 300ms after each keystroke before considering the term
.distinctUntilChanged() // ignore if next search term is same as previous
.switchMap(term => term // switch to new observable each time the term changes
// return the http search observable
? this.refundCaseService.search(term)
// or the observable of empty heroes if there was no search term
: this.test(term)
)
.catch(error => {
// TODO: add real error handling
console.log(error);
return Observable.of<any>();
});
}
test(term: string) {
console.log(term);
return Observable.of<any>();
}
This code is never reached, it doesn't enter the service neither the test function (I used breakpoints and console.log to make sure).
I don't understand how this is working.
Using: Angular 4.0.0 Angular-cli 1.0.6
Upvotes: 2
Views: 1813
Reputation: 5146
Check this excellent article from Christoph Burgdorf on THOUGHTRAM - Cold vs Hot Observables.
Basically, what you are dealing with here is known as a Cold Observable.
Cold observables start running upon subscription, i.e., the observable sequence only starts pushing values to the observers when Subscribe is called. (…) This is different from hot observables such as mouse move events or stock tickers which are already producing values even before a subscription is active.
So, unless you subscribe to this.testing
or use the async
pipe in your template, no requests will be fired.
Upvotes: 1
Reputation: 40647
The other answers are correct that this is indeed a Cold Observable. However, the reason that this is actually working is the async
pipe of Angular.
The async
pipe that's been used in the example:
<div id="search-component">
<h4>Hero Search</h4>
<input #searchBox id="search-box" (keyup)="search(searchBox.value)" />
<div>
<div *ngFor="let hero of heroes | async"
(click)="gotoDetail(hero)" class="search-result" >
{{hero.name}}
</div>
</div>
</div>
because of this pipe this example is working.
The async pipe subscribes to an Observable or Promise and returns the latest value it has emitted. When a new value is emitted, the async pipe marks the component to be checked for changes. When the component gets destroyed, the async pipe unsubscribes automatically to avoid potential memory leaks.
Source: https://angular.io/api/common/AsyncPipe
tl;dr: you can't debug this code because it's being handled in the template/html.
Upvotes: 3
Reputation: 5327
You have to subscribe to the Observable otherwise it doesn't "listen" for changes.
this.testing.subscribe(
x => console.log('onNext: %s', x),
e => console.log('onError: %s', e),
() => console.log('onCompleted')
);
Upvotes: 1