0

I am basically calling an API on keyup event of a textbox using switchmap. The problem that I am facing is that switchmap doesn't cancel the previous ongoing API call when a new API call is made

import {AfterViewInit, Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import {fromEvent, Observable} from "rxjs";
import {debounceTime, distinctUntilChanged, map, switchMap} from "rxjs/operators";

@Component({
  selector: 'app-debounce-component',
  templateUrl: './debounce-component.component.html',
  styleUrls: ['./debounce-component.component.css']
})
export class DebounceComponentComponent implements OnInit,AfterViewInit {

  constructor() { }
  @ViewChild('searchinput') ele:ElementRef

  ngOnInit(): void {
  }

  ngAfterViewInit(): void {
    fromEvent(this.ele.nativeElement , 'keyup').pipe(
      debounceTime(1000),
      map(evt=>{

             return evt['target']['value']
      }),
      switchMap(value=>{
        console.log(value);
        return this.createObservable(value);
      }),
      distinctUntilChanged()
    ).subscribe() ;
  }

  createObservable(value):Observable<any>{

    return Observable.create(observer=>{
      fetch(`http://localhost:3000/courses/${value}`).then(res=>{
        res.json();
      }).then(body=>{
        observer.next(body);
        observer.complete();
      });
    })

  }

}
Mohammad Mirzaeyan
  • 845
  • 3
  • 11
  • 30
Slow Death
  • 31
  • 3
  • 1
    Is there a reason for using fetch directly instead of the Angular HttpClient? It handles request cancelation automatically – Alberto Chiesa Aug 20 '21 at 06:59
  • Agreed, just use Angular's HttpClient – Jeremy Thille Aug 20 '21 at 07:01
  • @A.Chiesa. Actually i am trying to learn rxjs switchmap and as per the docs rxjs switchmap should cancel an ongoing request if a new request get fired. I can use HttpClient but my concern is that why is switchmap not cancelling the ongoing api call when a new api call gets fired – Slow Death Aug 20 '21 at 07:09
  • 1
    Switch map is unsubscribing from the previous observable. The problem is not switchmap per se. It's your usage of fetch that doesn't connect the unsubscribe to the cancel request. HttpClient provides an extended implementation – Alberto Chiesa Aug 20 '21 at 07:17
  • Thankyou A. Chiesa. Your answer solved my problem – Slow Death Aug 20 '21 at 08:04

1 Answers1

2

Even though it's now possible (it wasn't for a long time) to abort requests made with fetch, you'll still need an AbortController to do so. Fortunately for us, RxJS has implemented an operator called fromFetch that handles this for us.

Simply do

fromFetch("https://api.github.com/users?per_page=5").pipe(
  switchMap(response => {

and it should work as you want!

Daniel B
  • 8,770
  • 5
  • 43
  • 76