0

I am working on one project where we are using search bar to search data from server and for that we are calling API on every character type.

Due to that if user types 10-20 characters in search bar it will call 20 requests.

Among 19 request no required at all so I want to cancel all perior request from advanced HTTP plugin in ionic 3.

Is there any way to cancel that request which is already in process ?

I am using below code for HTTP call:

    this.httpPlugin.setRequestTimeout(60);
    // this.httpPlugin.setHeader("content-type", "application/json");
    this.httpPlugin.setHeader('authorization', "Bearer " + token);
    console.log('Requested URL :-', this.url + 'faqmsDetails/faList?caseNum=' + searchText);
    this.httpPlugin.get(this.url + searchText, {}, {}).then((response) => {

       console.log("Response Success : " + JSON.stringify(response));
       let jsonResponse = JSON.parse(response.data);
       console.log("JSON OBJECT RESPONSE : " + jsonResponse);
       resolve(jsonResponse);

    }).catch(error => {
       reject(error);
    });

I search a lot but didn't find any fruitful solution.

for Search delay i have used debounce property of searchebar which will help me to delay in search while user typing but still some request are unwanted in process so I want to cancel that requests.

Let me know if any one have any solution or suggestions.

CodeChanger
  • 7,953
  • 5
  • 49
  • 80
  • use switchMap, you can refer to this [post](https://stackoverflow.com/questions/49152025/how-to-use-switchmap-to-cancel-pending-http-requests-and-taking-the-last-subscri). – wwood_cc Jul 04 '18 at 05:51

1 Answers1

0

debounce is what you need in the auto-search case. The tail input will be considered as the confirmed input, exactly same as submit button clicking, even though it turns out be unwanted eventually.

I'm not familiar with the httpPlugin underneath. If based on XMLHttpRequest, it is cancelable. If based on fetch API, it is not cancelable. Anyway you can cast the unwanted requests away.

One much more graceful solution is to introduce rxjs. See https://github.com/Reactive-Extensions/RxJS/blob/master/examples/autocomplete/autocomplete.js

Update:

Got stuck with controlling these event streams. I think rxjs is worth in this case.

<!doctype html>
<html>
  <head>
    <script src="https://cdn.bootcss.com/rxjs/5.4.3/Rx.js"></script>
  </head>
  <body>
    <input />
    <button>clear</button>
    <span id="result"></span>
    <script>
      function searchData(keyword) {
        console.log('to search: ' + keyword)

        return new Promise(resolve => {
          if (keyword) {
            setTimeout(() => resolve('result of ' + keyword), 2000)
          } else {
            resolve('cleared')
          }
        })
      }

      const input = document.querySelector('input')
      const clear = document.querySelector('button')
      const result = document.getElementById('result')

      const input$ = Rx.Observable.fromEvent(input, 'keyup')
                      .map(e => e.target.value)
                      .debounceTime(300)

      const clear$ = Rx.Observable.fromEvent(clear, 'click')
                      .map(() => {
                        input.value = ''
                        return ''
                      })

      const search$ = Rx.Observable.merge(input$, clear$)
                      .distinctUntilChanged()
                      .switchMap(searchData)
                      .subscribe(data => {
                        result.innerHTML = data
                        console.log(data)
                      })
    </script>
  </body>
</html>
ladjzero
  • 148
  • 7
  • I have already used 'debounce` for serchbar but while click on clear button I want to cancel my http request which i already requested. – CodeChanger Feb 26 '18 at 06:08
  • @CodeChanger theoretically Promise is not cancelable. The clear action is an especial input, to search data by empty string. The debounced data fetching function should handle this action. Just return null if there is no need to call server data. – ladjzero Feb 26 '18 at 07:02