Tuesday, September 6, 2016

Dynamic baseref with angular 2

Angular 2 determines how to load 'relative' links using this tag in the main index:

<base href="/">&lt
This isn't a great thing if you want to deploy to other than the root directory of a server. You can find many examples of this causing grief for developers.

Short of manually changing base href before you deploy, the most common solution seems to be to have a little bit of javascript emit the base href into the document before angular loads. Yuck. I managed to work up a more D.I. way to do this that I'll share. No guarantees that this is going to keep working in subsequent RCs (I'm still on 2.0.0-rc.5):

import {RouterModule} from '@angular/router';
import {APP_BASE_HREF} from '@angular/common';
import {ModuleWithProviders} from '@angular/core';
/* all your other imports */


const appRoutingProviders: any[] = [
  {
    provide: APP_BASE_HREF,
    useFactory: () => {
      return window.location.pathname;
    }, deps: [  ]
  }
];
const routingModule: ModuleWithProviders = RouterModule.forRoot(routingTable, {enableTracing: false, useHash: true});

@NgModule({
  declarations: [
    AppComponent, /* list all your other components here */
  ],
  imports: [
    BrowserModule,
    CommonModule,
    FormsModule,
    HttpModule,
    routingModule
  ],
  providers: [appRoutingProviders],
  bootstrap: [AppComponent],
  entryComponents: [AppComponent]
})
export class AppModule {
}


The basic idea is to build a bridge into the initial path then use that as the base. I've been looking for a less error-prone mechanism and haven't found it yet - certainly this could be a little more robust in the form of error checking. If you're like me and want to deploy by scp then it's better than the alternative, having to edit index.html based on where you deploy.

No comments:

Post a Comment