alia
alia

Reputation: 459

How to fire subscribe only when param or one key-value pair of query param changes

i have the following scenario where i want to fire the subscribe only when either the params of the url has changed or showList changes in the query param.Rest of the query param page=0&size=5&sort=name,asc is only added for cases like reload or navigating back to the same url and also gets added after the showList queryParam got added which leads to the subscribe getting fired twice.

The route changes in the following manner is i click on showList button

http://localhost:8080/org/acount/param1/param2?showList=true
http://localhost:8080/org/acount/param1/param2?showList=true&page=0&size=5&sort=name,asc

The second navigation happens because when showList is true an api call is made to fetch the list of accounts and if api returns back a non-empty result then page, size, sort is set.

Route changes to this if hide button is pressed

http://localhost:8080/org/acount/param1/param2?showList=false

I need to handle cases like reload + when back button is pressed too.

I have implemented the following to handle the above case but i know it's not the best possible solution:

this.params_subscribe = combineLatest([this.activatedRoute.params, this.activatedRoute.queryParams]).pipe(
      map(results => ({ param: results[0], query: results[1] }))
    ).subscribe(result => {
      let show_list: boolean = (result.query.showList === 'true');
      if ((JSON.stringify(result.param) !== JSON.stringify(this.prevParam)) || (result.query.showList !== this.prevQueryParam.showList)) {
        if (!this.from_ui || result.query.showList !== 'false') {
          if (result.param.teamId && result.param.breadcrumb) {
            ...
          }
          else {
            this.initialize()
          }
        }
      }
      this.prevParam = result.param;
      this.prevQueryParam = result.query;
    });

from_ui is used to prevent the function call if query param has changed by clicking the hideList button which sets showList to false.

Is there a better way to handle this?

Upvotes: 1

Views: 74

Answers (1)

Barremian
Barremian

Reputation: 31125

You could use the distinceUntilChanged operator with a custom comparator.

Try the following

combineLatest([
  this.activatedRoute.params, 
  this.activatedRoute.queryParams
]).pipe(
  map(results => ({ param: results[0], query: results[1] })),
  distinctUntilChanged((prev, curr) =>
    JSON.stringify(prev.result.param) === JSON.stringify(curr.result.param) &&
    prev.result.query.showList === curr.result.query.showList
  )
).subscribe(
  ...
);

Upvotes: 2

Related Questions