3

Is there a way to run a function when matched a specific URL. For example: If i matched a URL "/home". Would it possible to run this action

this.store.dispatch(new SampleAction())

  • 2
    When your url is matched then lets say your "HomeComponent" is loaded. Simply run this on ngOnInit() of your HomeComponent – MoxxiManagarm Oct 31 '19 at 14:26
  • 1
    @MoxxiManagarm. That's what i did. but what if you have many url to match. Would you run this on every ngOnInit() on every component? Is there a way on just a single file to do this? –  Oct 31 '19 at 14:28
  • 1
    So what's the problem to subscribe to the `router.events`, filter by some event `NavigationEnd` or `NavigationStart` (I don't know what do you need), then filter by the needed url and `switchMap` to the `store.dispatch`? – overthesanity Oct 31 '19 at 16:33

3 Answers3

2

1.- For a single Route:

You could just execute your function in the onInit()-function of your Component:

import { Component, OnInit } from '@angular/core';

@Component({
})
export class YourComponent implements OnInit {

  constructor() { }

  ngOnInit() {
//your code here
  }

}

As soon as your navigating to the route, your function will be executed. Note that your route should be added to your routing-moudle:

const routes: Routes = [
  {path: 'youRoute', component: YourComponent}
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule {
}

2.- Same Function multiple Routes

If you want to execute the same code for multiple routes you could listen to route changes. Your router outlet should look like this:

<router-outlet (activate)="routeChange()"></router-outlet>

And in your component:

  constructor(public route: Router) {}    

  myRoutes: string[] = ['/tools', '/home'];

  routeChange() {
    if (this.myRoutes.some(e => e === this.route.url)) {
      console.log('execute');
    } else {
      console.log('dont execute');
    }
  }
Felix Gerber
  • 1,615
  • 3
  • 30
  • 40
1

Can't you just put the dispatch in the constructor of the HomeComponent?

Otherwise you could use a guard for this:

Route:

  path: '/home', component: HomeComponent, canActivate: [DispatchGuard]

Guard

@Injectable()
export class DispatchGuard implements CanActivate {

  constructor() { }

  canActivate(): boolean {
    this.store.dispatch(new SampleAction())
    return true;
  }
}
Marcel Hoekstra
  • 1,334
  • 12
  • 19
1

The other answers here would work however another option is available if you are using the NGXS Router Plugin. You could listen to the stream for router actions e.g. RouterNavigation, then if the route matches what you are looking for, dispatch the action.

constructor(private actions$: Actions, private store: Store) {

// Listen to the NGXS action stream for when the router navigation changes
this.actions$
    .pipe(ofActionDispatched(RouterNavigation))
    .subscribe(({routerState}: RouterNavigation) => {

      // If routerState matches your conditions then dispatch the action
        if (routerState == ) { 
          this.store.dispatch(new SampleAction());
        }
     });
}
Garth Mason
  • 7,611
  • 3
  • 30
  • 39
  • Will i put this in a separate file and how would this run? Do i need to put in the providers? –  Nov 01 '19 at 02:14
  • 1
    Depending on how you want it to work, you could hook it into your main `app.component` or load it when the app starts up via `APP_INITIALIZER` – Garth Mason Nov 01 '19 at 02:18
  • Yes i want it to load on start of the app. Can you edit your code? Thanks –  Nov 01 '19 at 02:26
  • On startup you need to load it as a provider in your main `App.Module` - see the examples [here](https://angular.io/guide/dependency-injection-providers#predefined-tokens-and-multiple-providers) – Garth Mason Nov 01 '19 at 02:32
  • Thanks I tried providing it but it still not functioning. It doesn't appear in console when i tried console.log –  Nov 01 '19 at 02:55