3

We have upgraded our Angular 2 project to Release Candidate 4.

We are using HashLocationStrategy to be able to refresh a page in the browser (using BrowserSync). But with RC4 this no longer works. No component is loaded into the routeroutlet. However, using the routerlink of a menu item does work.

Is the HashLocationStrategy for RC4 broken, or are we not using it correctly? We haven't found any information on the Internet yet. (right now just trying to find our way through the Angular2 source code to find out what is going on)

Update: here is the code.

Also, we can't seem to find a way to get a default route working. Tried the empty path as seen below, tried the redirect...nothing seems to trigger a default route that will load a component into the route-outlet.

// boot:

import {bootstrap} from '@angular/platform-browser-dynamic';

import {AppComponent} from './app.component';

bootstrap(AppComponent)
    .catch(err => console.log(err));


// AppComponent:

import {Component, provide, ExceptionHandler} from '@angular/core';
import {HTTP_PROVIDERS, XHRBackend} from '@angular/http';
import {CORE_DIRECTIVES, LocationStrategy, HashLocationStrategy} from '@angular/common';
import {TranslatePipe, TranslateService, TRANSLATE_PROVIDERS} from 'ng2-translate/ng2-translate';

import {SideMenuComponent} from './navigatie/index';
import {AppSettingsService, Auth, MockBackendToggle} from './shared/index';
import {EssStorage} from './shared/ess-storage';
import {EssHttp} from './shared/ess-http';
import {DienstverbandService} from './dienstverband/shared/dienstverband.service';
import {HeaderMenuComponent} from './navigatie/headermenu/headermenu.component';
import {WerknemerService} from './werknemer/werknemer.service';
import {PersoonService} from './werknemer/persoon/shared/persoon.service';
import {RouterOutlet} from '@angular/router';
import {APP_ROUTER_PROVIDER} from './navigatie/routes';
import {AuthGuard} from './shared/auth/auth-guard';
import {EssExceptionHandler} from './shared/ess-exception-handler';


@Component({
    selector: 'ess-app',
    pipes: [TranslatePipe],
    directives: [CORE_DIRECTIVES, SideMenuComponent, HeaderMenuComponent, RouterOutlet],
    providers: [TRANSLATE_PROVIDERS, TranslateService, HTTP_PROVIDERS, EssHttp, WerknemerService, APP_ROUTER_PROVIDER, AuthGuard,
                AppSettingsService, Auth, DienstverbandService, PersoonService, provide(XHRBackend, {useClass: MockBackendToggle}),
                provide(LocationStrategy, {useClass: HashLocationStrategy}), provide(ExceptionHandler, {useClass: EssExceptionHandler})],
    template: `
    <div id='main'>
        <div class='header  hidden-xs' *ngIf="_auth !== undefined && _auth.isLoggedIn()">
            <header>
                <ess-headermenu></ess-headermenu>
            </header>
       </div>

        <div class='ess-sidemenu-container visible-lg' *ngIf="_auth !== undefined && _auth.isLoggedIn()">
            <ess-sidemenu></ess-sidemenu>
        </div>

        <div class='main-content-container col-lg-12'>
            <section> 
                <section id='content'>
                    <div>
                        <router-outlet></router-outlet>
                    </div>
                </section>
            </section>
        </div>
    </div>`
})
export class AppComponent { //..}

// routes:

import {provideRouter, RouterConfig} from '@angular/router';
import {DashboardComponent} from '../dashboard/index';
import {PersonaliaComponent} from '../werknemer/index';
import {LoginComponent} from '../login/index';
import {AuthGuard} from '../shared/auth/auth-guard';

export const appRoutes: RouterConfig = [
    {path: '',                      component: LoginComponent},
    {path: 'login/:url',            component: LoginComponent},
    {path: 'dashboard',             component: DashboardComponent},
    {path: 'personalia',            component: PersonaliaComponent,             canActivate: [AuthGuard]}
];

export const APP_ROUTER_PROVIDER = provideRouter(appRoutes);

Update:

When I navigate to a view by clicking on a link and using [routerLink], then the router-outlet gets filled with the correct Component. For instance when navigating to 'auto'.

<li class="submenuitem" [routerLink]="['auto']"><a href="#"><span>{{'AUTO' | translate}}</span></a></li>

But when I for instance refresh the 'auto' page, the router-outlet becomes empty.

Andre
  • 145
  • 1
  • 11
  • Where are you providing the `HashLocationStrategy`? If in the `bootstrap` call, try moving it into the root component's `providers` array. – rinukkusu Jul 08 '16 at 11:52
  • 1
    Our bootstrap call has zero providers. We have all 'global' providers inside the providers array of our AppComponent. – Andre Jul 08 '16 at 12:15
  • Add the bootstrap code in the question – Siraj Jul 08 '16 at 22:15
  • I can reproduce this issue as well. The router falls uses HTML 5 location strategy as default even if I define the ``LocationStrategy`` in the root component. – Alexander Heimbuch Jul 09 '16 at 08:06
  • You need to show the bootstrap code, before any help can be provided – Siraj Jul 09 '16 at 08:23

1 Answers1

7

In Angular 2 rc4, it appears LocationStrategy has been moved from router to common. You'll have to import it from there.

Also note the curly brackets around the 'provide' line.

rc4: main.ts

// Imports for loading & configuring the in-memory web api
import { XHRBackend } from '@angular/http';

// The usual bootstrapping imports
import { bootstrap }      from '@angular/platform-browser-dynamic';
import { HTTP_PROVIDERS } from '@angular/http';

import { AppComponent }         from './app.component';
import { APP_ROUTER_PROVIDERS } from './app.routes';
import { Location, LocationStrategy, HashLocationStrategy} from '@angular/common';

bootstrap(AppComponent, [
    APP_ROUTER_PROVIDERS,
    HTTP_PROVIDERS,
    {provide: LocationStrategy, useClass: HashLocationStrategy}
]);

rc5: app.module.ts

In rc.5 this is changed again because of the major changes to main.ts. Hashlocationstrategy is now implemented in app.module.ts as an option when importing the RouterModule.

@NgModule({
imports: [routing, RouterModule.forRoot(routing,{ useHash: true })],

2.0.0: app.module.ts

In Angular 2.0.0 (= release version) Hashlocationstrategy stayed in app.module.ts, but the phrasing changed a little bit. It's now sitting with the providers.

...
import { LocationStrategy, HashLocationStrategy } from '@angular/common';
...  

@NgModule({
  bootstrap: [AppComponent],
  imports: [
    //all your modules
  ],
  declarations: [
    //all your components
  ],
  providers: [
    //all your services
    {provide: LocationStrategy, useClass: HashLocationStrategy},
  ]
})
KDC
  • 1,411
  • 5
  • 17
  • 35