Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to trigger route resolver manually

I'm resolving a user before accessing the account fragment of my user page :

app-routing.component.ts

{
  path: 'users/:id',
  component: UserComponent,
  resolve: {user: UsersService},
  children: [
    {path: '', pathMatch: 'full', redirectTo: 'account'},
    {path: 'account', component: UserAccountComponent},
    {path: 'sites', component: UserSitesComponent}
  ]
}

users.service.ts

resolve(route: ActivatedRouteSnapshot, r: RouterStateSnapshot) {
  return this.getUser(route.params['id']);
}

user-account.component.ts

ngOnInit() {
  this.route.parent.data.subscribe(data => {
    this.user = data['user'];
    // Initialize the form and its validators
    this.initForm();
  });
}

In the user account component I can save or reset the form. In both cases I'd like to update the user of the component and to reset the form and the validators. Ideally It'd like the subscription to be triggered again.

Any idea how to trigger the resolver manually ?

(I used to re-navigate to the same route modulo a random number as the last fragment, but since I exploded my user page into parent/children routes, the resolver, within the parent, is not called anymore when the last fragment changes)

like image 556
Max Avatar asked Jan 23 '17 11:01

Max


People also ask

How do you test angular resolvers?

To test the resolver we need to render RouterOutlet . const fixture = MockRender(RouterOutlet); Additionally, we also need to properly customize mocked services if the resolver is using them to fetch data. const dataService = TestBed.


2 Answers

I agree with "Woot", but if you want to trigger the resolver again, go to your routing module and add

runGuardsAndResolvers: "always"

Now you can navigate on the same page again an the resolver will run again. But be aware only the resolver will run again, no other lifecyle, like "ngOnInit".

Example according to you code

app-routing.component.ts

{
  path: 'users/:id',
  component: UserComponent,
  resolve: {user: UsersService},
  children: [
    {path: '', pathMatch: 'full', redirectTo: 'account'},
    {path: 'account', component: UserAccountComponent, runGuardsAndResolvers: "always"},
    {path: 'sites', component: UserSitesComponent}
  ]
}

Now if you route to the same page again the subscription on your user-account.component.ts will be triggered again

like image 73
Murolack Avatar answered Sep 22 '22 13:09

Murolack


If you need to rerun your guards and resolvers for specific conditions (specific queryparams, ...) there also the more flexible option to pass a function to runGuardsAndResolvers in the routing module. Example:

const routes: Routes = [
  {
    path: 'home/:id',
    component: HomeComponent,
    ...
    runGuardsAndResolvers: (curr: ActivatedRouteSnapshot, future: ActivatedRouteSnapshot) => {
      // inspect the current router state and then return true|false
      return false;
    }
  }
];

Example taken from the following article:

https://juristr.com/blog/2019/01/Explore-Angular-Routers-runGuardsAndResolvers/

like image 38
Mariejoe Chahine Avatar answered Sep 22 '22 13:09

Mariejoe Chahine