0

I need to get my [options] array filled dynamically, once the user has finished typing i need to make an API call and get my list of options.

In order to avoid multiple API calls, I would like to use something like rxjs debounceTime(1000);

Is there any way to use debounceTime? Or are there any other recommended options to use?

Niveditha Karmegam
  • 742
  • 11
  • 28

2 Answers2

1

You can use this trick using buffer and api call instead of ajax

import { fromEvent, timer } from 'rxjs';
import { debounceTime, map, buffer, switchMap } from 'rxjs/operators';

let input = document.getElementById('example');
let input$ = fromEvent(input, 'keyup');

let breakWhen$ = timer(1000);
let debounceBreak$ = input$.pipe(
debounceTime( 2000 )
);

let stream$ = input$.pipe(
  map( ev => ev.key),
  buffer(debounceBreak$),
  switchMap((allTypedKeys) => {
  // do ajax
  console.log('Everything that happened during 2 sec', allTypedKeys)
  return of('ajax based on ' + input.value);
});
);

stream$.subscribe((data) => console.log( 'values',data ));
  • Thank you for the answer. But the issue i'm facing is rather than a input field, im using ngx-select-dropdown. I tried to do something very similar to this, but onChange event after i debounce it, when i try to map the input, its always undefined. – Niveditha Karmegam Jan 21 '20 at 07:01
  • 1
    use ngx-mat-select-search(https://www.npmjs.com/package/ngx-mat-select-search) i think this will solve your problem – Navruzbek Noraliev Jan 21 '20 at 13:41
  • This was a wonderful solution. The *server-side search* provided by this library is perfection. But sadly since it required angular/material, the UI was completely messed up and it wasn't usable. Hence, i cant mark it as the correct answer. But I will up vote this, definitely would help someone else :) – Niveditha Karmegam Jan 22 '20 at 05:52
0

Like Navruzbek mentioned 'ngx-mat-select-search' could be used for server side dropdown search.

However if you want to use your current library and add debounceTime to it, a workaround would be using a Subject. Like suggested by https://stackoverflow.com/a/39960980/7763714

The solution that worked for me:

searchTextChanged=new Subject<string>();

// make the server-side call in the subscrivbe function
ngOnInit() {
  this.searchTextChanged.pipe( debounceTime(1000), distinctUntilChanged())  .subscribe((value)=> this.outerValuedChanged(value));
}

addressSearchChanged(searchText: string) {
  if (searchText.length >=3) {
    this.searchTextChanged.next(searchText);
  }
}

// dummy function
outerValuedChanged(value: string) {
  console.log('value:', value);
  return 'test';
}
<ngx-select-dropdown (searchChange)="addressSearchChanged($event)" formControlName="inputAddressFormControl" [multiple]="false" [config]="config" [options]="addressList"></ngx-select-dropdown>
Niveditha Karmegam
  • 742
  • 11
  • 28