I'm facing an issue currently, where a first search could take 5 seconds, and second one that takes 2 seconds, problem is, the first search which takes longer, will "erase" the results of the request that was done after, because the calls ends after.
I tried to read about
switchMap
in rxJs and tried to use it, but from what I try, it doesn't unsubscribe from previous request and erases the result.
There is probably something I'm doing wrong here but I can't exactly point out what is the issue.
Merge has 3 sources of change in the result ( pagination, sorting, or new search criteria ), and the call to sendSearchCriteria returns the data used.
sendSearchCriteria returns an Observable
is there anything that comes in mind for you, that I'm doing wrong ?
Thank you for your help,
private loadDogsResults = (filtersInformation: FilterSearchCriteria) => {
merge(this.sort.sortChange, this.paginator.page, of(filtersInformation))
.pipe(
distinctUntilChanged(),
tap(() => (this.isLoading = true)),
switchMap(() => this.sendSearchCriteria(filtersInformation)),
//mergeMap(() => this.sendSearchCriteria(filtersInformation)),
map(data => this.formatResults(data)),
finalize(() => (this.isLoading = false)),
catchError(error => this.handleError(error)),
takeUntil(this._onDestroy$)
)
.subscribe((result: any[]) => {
if (result.length > 0) {
this.setDisplayedColumns(result[0]);
}
this.isLoading = false;
});
}
Which event triggers the search
? This event should be the source of your Observable
, that will be "piped" with switchMap
operator.
As I can see here, if you call loadDogsResults()
for each event, it won't work as you create a new Observable
each time. of(filtersInformation)
is an Observable which emits the filtersInformation
value ONCE when the observable is subscribed, I don't think that it's the expected behavior.
You are doing a merge on 3 separate observables, which will result in you entering the pipe on 3 separate occasions, and firing off 3 separate calls to sendSearchCriteria. If what you want to do is call sortChange and page, get the results of both and then call sendSearchCriteria, you can...
private loadDogsResults = (filtersInformation: FilterSearchCriteria) => {
forkJoin(this.sort.sortChange, this.paginator.page)
.pipe(
distinctUntilChanged(),
tap(() => (this.isLoading = true)),
switchMap(() => this.sendSearchCriteria(filtersInformation)),
//mergeMap(() => this.sendSearchCriteria(filtersInformation)),
map(data => this.formatResults(data)),
finalize(() => (this.isLoading = false)),
catchError(error => this.handleError(error)),
takeUntil(this._onDestroy$)
)
.subscribe((result: any[]) => {
if (result.length > 0) {
this.setDisplayedColumns(result[0]);
}
this.isLoading = false;
});
}
However keep in mind in your subscribe you will only have access to the response from sendSearchCriteria.
A colleague helped me find the issue :) we tried forkJoin, combineLatest and multiple options but biggest issue was initialization/subscription done in an odd way.
we now created a searchTriggerSubject and added those lines
private initializeSubscription() {
this.searchTriggerSubscription = this.searchTriggerSubject.pipe(
tap(() => (this.isLoading = true)),
switchMap(() => this.sendSearchCriteria(this.claimsFilters)),
map(data => this.formatResults(data)),
catchError(error => this.handleError(error)),
takeUntil(this._onDestroy$)
).subscribe((result: any[]) => {
if (result.length > 0) {
this.setDisplayedColumns(result[0]);
}
this.isLoading = false;
});
}
private initializeSearchTriggerValues() {
this.sort.sortChange.subscribe(() => this.searchTriggerSubject.next())
this.paginator.page.subscribe(() => this.searchTriggerSubject.next())
this.filtersSubscription = this.claimsFiltersService.getFilterValues()
.pipe(
filter(filters => filters !== null),
tap((filter) => this.claimsFilters = filter)
)
.subscribe(() => this.searchTriggerSubject.next());
}
the filters were coming form a service so this is what we did to avoid the issue.
Some refactoring was needed
Thanks a lot everyone for the different leads, having multiple subjects makes it easier
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.