0
votes

Trying to search trough extrnal api Weather servis.

Api is tested and works fine.

Problem: Enter value in search bar and main Search method from servis is not called. That is reason why request is not sent.

I follow tutorial from angular official documentation: https://angular.io/tutorial/toh-pt6#search-by-name

And this not work.

Search Component:

export class SearchCityComponent implements OnInit {
  cities$: Observable<City[]>
  private searchTerms = new Subject<string>()

  constructor(private weaterService: WeatherService) {}

  // Push a search term into the observable stream.
  search(term: string): void {
    this.searchTerms.next(term)
  }

  ngOnInit(): void {
    this.cities$ = this.searchTerms.pipe(
      // wait 300ms after each keystroke before considering the term
      debounceTime(300),

      // ignore new term if same as previous term
      distinctUntilChanged(),

      // switch to new search observable each time the term changes
      switchMap((term: string) => this.weaterService.searchCities(term))
    )
  }
}

Service:

 /* GET cities whose name contains search term */
  searchCities(term: string): Observable<City[]> {
    if (!term.trim()) {
      return of([])
    }
    return this.http
      .get<City[]>(`${this.citiesUrl}/?query=${term}`, httpOptions)
      .pipe(
        tap(_ => this.log(`found cities matching "${term}"`)),
        catchError(this.handleError<City[]>("searchCities", []))
      )
  }

When I enter in search input some value:

In Search Comnponent in ngOnInit() last line of code is Not called search function from services?

 switchMap((term: string) => this.weaterService.searchCities(term))
3

3 Answers

0
votes

An observable will be triggered only if it's needed, to tell to an Observable that you need it you have to subscribe to it :

    this.searchTerms.pipe(
      // wait 300ms after each keystroke before considering the term
      debounceTime(300),

      // ignore new term if same as previous term
      distinctUntilChanged(),

      // switch to new search observable each time the term changes
      switchMap((term: string) => this.weaterService.searchCities(term))
    ).subscribe()
0
votes

You forgot subscribe with switchMap!

As per the angular docs:

An Observable instance begins publishing values only when someone subscribes to it. You subscribe by calling the subscribe() method of the instance, passing an observer object to receive the notifications.

0
votes

Your implementation is alright. You just have to unwrap the cities$ Observable in your Template using an async pipe. It's recommended to use the async pipe wherever possible. Just makes the code less verbose.

Doing something like this would help:

<ul>
  <li *ngFor="let city of cities$ | async">
    {{ city.name }}
  </li>
</ul>

Here's a Working Sample StackBlitz for your ref.