0

I have the following Route Config:

{
    path: ':id',
    component: MyComponent,
    resolve: {
        data: MyResolver
    }
}

The Resolver will simply do an HTTP call to fetch some data:

resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Artist> {
    return this.service.getData(route.params.id);
}

The Component contains some tabs and has some functionality to set / change matrix params accordingly.

  • When first visiting the route, the URL will be http://.../#/123
  • When the user clicks a tab, it will change to http://.../#/123;tab=foo

When the user now manually changes the URL the Resolver will run again. This is okay when he changes the :id. But it shouldn't happen when he only changes the tab param.

Any idea how to do this?

I thought about adding some distinctUntilChanged into the resolver, but I couldn't get it working. Something like:

return of(route.params.id).pipe(
    distinctUntilChanged(),
    switchMap(val => this.service.getData(val)
)

But maybe I just did it wrong.

Benjamin M
  • 23,599
  • 32
  • 121
  • 201
  • It depends on how exactly it should work. What's the reasoning behind *it shouldn't happen when he only changes the tab param*? *When the user now manually changes the URL the Resolver will run again* - this is an edge case that should generally be ignored. Obviously, this won't work with distinctUntilChanged() in resolver. of(route.params.id) is an observable with single value. You don't have access to previous state in resolve(). – Estus Flask Mar 29 '18 at 00:27
  • Of course it's an edge case. But if possible, it should be covered. The behavior should simply be: if user changes `:id`, then run the resolver, else don't run it. – Benjamin M Mar 29 '18 at 01:36
  • @BenjaminM what do you mean manuallay changed? You mean change from the browser and then force reload ? If so wouldn't that clear the angular module/services hence the reresoilve ? – Nuru Salihu Mar 29 '18 at 02:57
  • No, you can't do that. The resolver re-runs because the app is reloaded when a user changes url manually. It's same thing as avoiding the resolver when a user closes a tab/window and reopens it. It's different app instance, and the app is unaware of any changes in `tab` param. You can cache services in local storage/indexeddb if you want to reduce the amount of overall requests, but this shouldn't be tied to this edge case. – Estus Flask Mar 29 '18 at 10:17
  • The app doesn't reload. If I don't use any resolver and put a `console.log()` inside my component constructor, I can see that it only is getting called once. Now I can change the URL params in the browser and the log message **won't** appear again. Then I have to handle the changes via `activatedRoute.params.subscribe(..)`. But it works as expected and this way I can handle each param differently. I hoped this was possible for resolvers, too. But doesn't seem so :( – Benjamin M Mar 29 '18 at 11:30

0 Answers0