I would improve the performance issue that you have.
User can search the same thing a lot of times and in your case for the same string you are calling a new API, but the result will be the same.
In this case, I recommend adding caching already used API with the same string.
What we can do?
we can use shareReplay
in combination with Map
for your getList
method.
I made an example of how it will look:
import { Component } from "@angular/core";
import { mergeMap, exhaustMap, concatAll, shareReplay } from "rxjs/operators";
import { HttpClient } from "@angular/common/http";
import { from, Observable, Subject } from "rxjs";
@Component({
selector: "my-app",
template: `
<input
type="number"
min="1"
max="10"
(keyup)="onInputChange($event.target.value)"
/>
`,
styleUrls: ["./app.component.css"]
})
export class AppComponent {
private readonly products = new Map<string, Observable<any>>();
constructor(private http: HttpClient) {}
ngOnInit() {}
onInputChange(value) {
console.log(value);
this.getList(value).subscribe();
}
getList(param) {
// this.loader = true;
const cacheKey = param;
if (!this.products.get(cacheKey)) {
this.products.set(
cacheKey,
this.http
.get("https://jsonplaceholder.typicode.com/todos/" + param)
.pipe(shareReplay(1))
);
}
return this.products.get(cacheKey);
}
}
In accordance with the screeshot in your case, Based on your code you will have 7 API call!!!
In console, you can see set of user input 1, 12, 123, 12, 1, 12, 123
You will have:
- two calls of API for -
1
- two calls of -
123
- and tree call of =
12
Yes, I saw that you added debounceTime
and distinctUntillChanged
- but the issue still exists
and we can reduce it to 3 unique API calls
So, Each searchable string we will store in Map as key, and API with shareReaplay
(to avoid duplicate call API) as value.
And each time when we want call product we will check if API already exist in Map
and if exist we will return the already used API
if (!this.products.get(cacheKey)) {
this.products.set(
cacheKey,
this.http
.get(url + param)
.pipe(shareReplay(1))
);
}
return this.products.get(cacheKey);
You can try it in: https://stackblitz.com/edit/angular7-rxjs-cz6pcs?file=src/app/app.component.ts