0

Hi I am having trouble with my subject subscription and my search call. I want to cancel the previous call in favor of the current one. I have search through previous threads but have not had success with finding an answer.

I know I am supposed to use switchMap() but I am not having success with it. It continues all calls regardless of state. I think it mught have to do with the way I have set things up, in that I am not returning the response I am setting it. So there is no single observable reference..?

All help is appreciated!

Please see code below:

ngOnInit() {
// I subscribe to the Subject Observable here
this._searchService.quickSearch$
  .pipe(
    debounceTime(1000),
    distinctUntilChanged()
  )
  .subscribe(
    // when value has changed I call runSearch
    (queryString) => {this.runSearch(queryString);
  }
  );
}

runSearch:

runSearch(searchString: any) {
this.quickSearch.runSearch(searchString).pipe(
   //Not working as expected
    switchMap(() => {
      console.log('switchMap has bee fired');
      return this.quickSearch.runSearch(searchString);
    })
).subscribe(
    (response) => {
    //  set the two way bind here
    this.apiResponse = response;
  },
  (error) => {
    console.log('ERROR!!!');
  },
  () => {
    // this is fired when the observable is closed
    console.log('I have been unsubscribed');
  }
  );
 }

quicksearch service:

  runSearch(search: string): Observable<QuickSearch[]> {

   ...

    return this.http.get<QuickSearch[]>(this.api.url, { params: param, headers: header })
      .pipe(
        map((data: any) => {
             return data.map((item: any[]) => this.adapter.adapt(item));
        }
        ),
        catchError(error => error)
      );

  }

Thanks

UPDATE

I still have not found the answer to this question. So I am going to try to rephrase it.

I have 5 parts to this:

    Input box ([])-> 
    rxjs-Subject (input-text)-> 
    runSearch(input-text) -> [ handles response ] 
    _service.runSearch(input-text) ->
    http().get(input-text) => response

when the input box is changed then run search is called in which the search service is subscribed too this does not return

Natdrip
  • 1,144
  • 1
  • 11
  • 25

1 Answers1

2

The problem is that every time this._searchService.quickSearch$ emits you're calling runSearch method that every time creates a new chain so even when you have switchMap it makes no difference.

Instead you should put switchMap to the first chain:

this._searchService.quickSearch$
  .pipe(
    debounceTime(1000),
    distinctUntilChanged(),
    switchMap((searchString) => this.quickSearch.runSearch(searchString)),
  ).subscribe(
    (response) => {
      this.apiResponse = response;
    },
    ...
  );
bryan60
  • 28,215
  • 4
  • 48
  • 65
martin
  • 93,354
  • 25
  • 191
  • 226
  • This isn't working quicksearch$ is a subject so when it changes only the search string changes. when the string changes it currently calls runSearch. runSearch doesn't return anything to quick search subscribe. – Natdrip Mar 26 '19 at 18:29
  • In your code runSearch returns an Observable. I don’t know what you mean by “when subject changes”. You create a new subject instance on every key input? – martin Mar 26 '19 at 18:52
  • The this._searchService.quickSearch$ is a Subject I only subscribe once. in the oninit I use this as a central service for input changes. when a change is detected that is when pass the changed value to the runSearch. – Natdrip Mar 26 '19 at 20:26
  • this is very close to being correct... you just need to do this `switchMap((searchString) => this.quickSearch.runSearch(searchString)),` but otherwise this answer has it right, the runSearch in your component needs to be done away with. You keep creating new subscriptions everytime you call that function so it cannot switch ever. You need to maintain a single subscription so that it can switch appropriately. – bryan60 Apr 25 '19 at 21:06