Skip to content

Instantly share code, notes, and snippets.

@rgolea
Last active June 21, 2021 14:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rgolea/2d87adecbd7df0e133f4ca2a31e2db51 to your computer and use it in GitHub Desktop.
Save rgolea/2d87adecbd7df0e133f4ca2a31e2db51 to your computer and use it in GitHub Desktop.
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subject } from 'rxjs';
import { distinctUntilChanged } from 'rxjs/operators';
import { FormControl } from '@angular/forms';
import { SomeService } from './some-service';
import { autocomplete } from './autocomplete.operator';
@Component({
selector: 'app-component',
templateUrl: './app-component.html',
styleUrls: ['./app-component.scss']
})
export class AppComponent implements OnInit, OnDestroy {
private destroy$ = new Subject();
public formControl = new FormControl('');
constructor(
private readonly someService: SomeService
){}
ngOnInit(){
this.formControl.valueChanges.pipe(
autocomplete(5000, (controlValue) => this.someService.search(controlValue)), //search with debounce
takeUntil(this.destroy$) //cleanup
).subscribe(val => console.log('Results: ', val)) //This should only happen with a debounce of 300ms
}
ngOnDestroy(){
this.destroy$.next();
}
}
import { debounceTime, switchMap, takeUntil, skip } from 'rxjs/operators';
import { Observable } from 'rxjs';
export const autocomplete = (
time: number, //debounce
selector: (...args: any[]) => Observable<any>
) => (source$: Observable<any>) =>
source$.pipe(
distinctUntilChanged(), / only emit distinct objects, based on last emitted value so you're not triggering two queries
debounceTime(time),
switchMap((...args: any[]) =>
selector(...args).pipe(takeUntil(source$.pipe(skip(1))))
)
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment