Angular2 beta getting exception “No provider for Router! (RouterLink -> Router)”

angularangular2-routingtypescript

I have been banging my head against this for two days now. I am trying to implement some simple routing in Angular2 beta0.0.2. Please note that I am using typescript.

So what I understand is that I need to bootstrap my root app component with ROUTER_PROVIDERS so that these services are available to my who app AND set the directives for the components that want to implement routing to ROUTER_DIRECTIVES.

Here is what I have:

//ANGULAR  ******************************
import {provide, Component} from 'angular2/core';
import {bootstrap} from 'angular2/platform/browser';
import {
        APP_BASE_HREF,
        ROUTER_DIRECTIVES,
        ROUTER_PROVIDERS,
        HashLocationStrategy,
        LocationStrategy,
        RouteConfig,
        } from 'angular2/router';

//COMPONENTS  ******************************
import {ShiftCalendarComponent} from './components/calendar/shift-calendar.component';
import {ShiftAdminComponent} from './components/admin/shift-admin.component';
import {ShiftListComponent} from './components/shifts/shift-list.component';

//CLASS  ******************************
@Component({
    selector: 'shift-app',
    directives: [ROUTER_DIRECTIVES],
    template: `<div>
                 <nav>
                     <h3> Navigation: </h3>
                     <ul>
                         <li><a [routerLink]="['Calendar']" > Home </a></li>
                         <li><a [routerLink]="['Admin']" > About </a></li>
                         <li><a [routerLink]="['Shifts']" > Contact us </a></li>
                     </ul>
                 </nav>            
                 <router-outlet></router-outlet>
             </div>`
})
@RouteConfig([
    { path: '/', name: 'root', redirectTo: ['/Calendar'] },
    { path: '/calendar', name: 'Calendar', component: ShiftCalendarComponent },
    { path: '/admin', name: 'Admin', component: ShiftAdminComponent },
    { path: '/shifts', name: 'Shifts', component: ShiftListComponent }
])
export class ShiftApp { } 

//BOOTSTRAP   ******************************
    bootstrap(ShiftApp, [
        ROUTER_PROVIDERS, 
        provide(LocationStrategy, { useClass: HashLocationStrategy }),
        provide(APP_BASE_HREF, { useValue: '/' })    
    ]);

The angular app loads and the template is displayed, but no link works and I get the following error in my console:

EXCEPTION: No provider for Router! (RouterLink -> Router) angular2.dev.js

In my index.html (which i call view.html) I have linked to all the relevant libraries and have included router.dev.js and the sources tab of my console shows me that all the needed scripts are successfully loaded.

I have read about every stack overflow question with router link errors for Angular2 and the entire router docs but cannot find why mine is not working. As far as I can tell my code matches the Angular2 Documentation

This documentation shows that the ROUTER_DIRECTIVES includes the directives like RouterOutlet and RouterLink

Question?

If I am successfully setting the directives for the component to ROUTER_DIRECTIVES, why am I getting the "No provider for Router! RouterLink" error?

Best Answer

Move your bootstrapping process into s separate file:

import {bootstrap} from 'angular2/platform/browser';
import {provide, Component} from 'angular2/core';
import {ShiftApp} from './app.component';

import {
    APP_BASE_HREF,
    ROUTER_DIRECTIVES,
    ROUTER_PROVIDERS,
    HashLocationStrategy,
    LocationStrategy
} from 'angular2/router';

bootstrap(ShiftApp, [
    ROUTER_PROVIDERS,
    provide(LocationStrategy, { useClass: HashLocationStrategy }),
    provide(APP_BASE_HREF, { useValue: '/' })
]);

Import that new file in your index.html:

System.config({
    packages: {
        app: {
            format: 'register',
            defaultExtension: 'js'
        }
    }
});
System.import('app/boot')
    .then(null, console.error.bind(console));

Advantages of doing that can be found here.

Also as mentioned in the comment, bootstrap your root component instead of a child component.