Reputation: 231
Based off the search in the angular.io tour of heroes tutorial, I've created a simple animal search using an observable. It all works fine, however I'd now like to clear the values in the search, and clear the result list, when I select a result.
I've created a method to clear the input value on clicking the link, expecting that the observable would update and clear, unfortunately that doesn't happen, and the drop down list remains. I've tried reassigning the observable, which works, but then the observable is unsubscribed, something I don't want to do.
I'm sure this is a case of me not understanding fully how to work with observables yet, so hoping you guys could help me out.
Thanks, heres my code.
import { Component, OnInit } from '@angular/core';
import {Observable, Subject} from 'rxjs'
import {
debounceTime, distinctUntilChanged, switchMap
} from 'rxjs/operators';
import { AnimalService } from '../services/animal.service';
import { Animal } from '../models/animal';
@Component({
selector: 'app-animal-search',
templateUrl: './animal-search.component.html',
styleUrls: ['./animal-search.component.css']
})
export class AnimalSearchComponent implements OnInit {
animals$: Observable<Animal[]>;
private searchTerms = new Subject<string>();
private searchTerm: string;
constructor(private animalService: AnimalService) { }
search(term: string):void {
this.searchTerms.next(term);
}
ngOnInit() {
this.animals$ = this.searchTerms.pipe(
debounceTime(300),
distinctUntilChanged(),
switchMap((term: string) => this.animalService.searchAnimals(term)),
);
this.animals$.subscribe( )
}
clearSearch()
{
//PART THAT ISNT WORKING
this.searchTerm = "";
this.searchTerms = new Subject<string>();
}
}
<div id="search-component" class="search-component-container">
<input #searchBox id="search-box" [(ngModel)]="searchTerm" (keyup)="search(searchBox.value)" class="search-component-input" />
<ul class="search-result">
<li *ngFor="let animal of animals$ | async" >
<a routerLink="/animal/{{animal.id}}" (click)="clearSearch()">
{{animal.Name}}
</a>
</li>
</ul>
</div>
Upvotes: 4
Views: 28112
Reputation: 32535
when you do
this.searchTerms = new Subject<string>();
you are losing the subject that you have configured pipe for in onInit, as this is brand new subject instance.
you can just emit next value to clear it out using subject.next
Upvotes: 2
Reputation: 11474
Not sure exactly what you are trying to achieve, but, based on your question, it would seem like you would want to do the following:
clearSearch()
{
this.searchTerms.next('');
}
Depending on what your desired result is though, you could do the following as well:
initAnimals() {
if (this.animals$) {
this.animals.unsubscribe();
}
this.animals$ = this.searchTerms.pipe(
debounceTime(300),
distinctUntilChanged(),
switchMap((term: string) => this.animalService.searchAnimals(term)),
);
this.animals$.subscribe( )
}
ngOnInit() {
this.initAnimals();
}
clearSearch() {
this.initAnimals();
}
Upvotes: 7