Scipion
Scipion

Reputation: 11888

Angular2 Using Router in an Injectable service

I want to use the Router object in a service to allow to navigate to my different routes.

My AppComponent is looking like this :

@Component({
    selector: "app",
    templateUrl: "app/app.html",
    directives: [ROUTER_DIRECTIVES]
})
@RouteConfig([
  {
    path: "/home",
    name: "Homepage",
    component: HomepageComponent,
    useAsDefault: true
  },{
    path: "/home2",
    name: "Homepage2",
    component: HomepageComponent2
  }
])
export class AppComponent {
    constructor (private _externalService: ExternalService) {}

}

and ExternalService :

@Injectable()
export class ExternalService {
    constructor (_router: Router) {}
    ...
}

This code is failing saying that I can't instantiate Router inside ExternalService. I reckon this is due to RouteConfig not being available there. I also tried adding _router: Routerinside my AppComponent constructor and it works there. How can I use a Router instance inside my ExternalService ?

EDIT: Here is my app's bootstrap file :

import { bootstrap } from "angular2/platform/browser"
import { ROUTER_PROVIDERS } from "angular2/router"
import { ExternalService} from "./utils/external.service"
import { AppComponent } from "./app.component"
import { HTTP_PROVIDERS } from "angular2/http"

bootstrap(AppComponent, [ROUTER_PROVIDERS, HTTP_PROVIDERS, ExternalService, provide(LocationStrategy, {useClass: HashLocationStrategy})])

Upvotes: 2

Views: 9397

Answers (2)

Maximilian Riegler
Maximilian Riegler

Reputation: 23506

When you're providing the ExternalService in your bootstrap(), then you have to provide the ROUTER_PROVIDERS there, too. Otherwise Angular doesn't know how to instantiate a Router for your ExternalService.

bootstrap(AppComponent, [
    ROUTER_PROVIDERS,
    ExternalService
]);

Plunker for example usage (seems to work fine)

Upvotes: 1

Günter Zöchbauer
Günter Zöchbauer

Reputation: 657476

Seems work fine to directly inject the router to a service. I also tried injecting to the root component and passing to the service but when the direct way is working there should be no need

import {Component, Injectable, provide} from '@angular/core';
import {Router, Routes, ROUTER_PROVIDERS, ROUTER_DIRECTIVES} from '@angular/router';
import {LocationStrategy, HashLocationStrategy} from '@angular/common'; 

@Injectable()
export class ExternalService {
  //router:Router;
    constructor (private router: Router) {}

    navigate() {
      this.router.navigate(['/article']);
    }
}


@Component({
  selector: 'root',
  template: `
  <h2>Root</h2>
  `,
})
export class RootComponent {
}


@Component({
  selector: 'article',
  template: `
  <h2>Article</h2>
  `,
})
export class ArticleComponent {
}


@Component({
  selector: 'my-app',
  providers: [ExternalService, ROUTER_PROVIDERS, provide(LocationStrategy, {useClass: HashLocationStrategy})],
  directives: [ROUTER_DIRECTIVES],
  template: `
    <div>
      <h2>Hello {{name}}</h2>
      <router-outlet></router-outlet>
    </div>
    <button (click)="externalService.navigate()">Article</button>
  `,
})
@Routes([
  { path: '/article', component: ArticleComponent },
  { path: '/', component: RootComponent }
  ])
export class App {
  constructor(private externalService: ExternalService) {
    //externalService.router = router;
    this.name = 'Angular2 (Release Candidate!)'
  }
}

Plunker example

Upvotes: 4

Related Questions