LozBlake15
LozBlake15

Reputation: 231

Angular - Clear Observable on Click

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

Answers (2)

Antoniossss
Antoniossss

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

peinearydevelopment
peinearydevelopment

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

Related Questions