Search code examples
angularroutesangular4-router

Angular 4 - RouterOutlet 404 Error


My angular 4 app is hosted inside a 'Website' as an 'Application' in IIS let's say 'MyApp' and I've generated production build using angular-cli by using this command:

ng build --prod --base-href=/MyApp/

I also have the Url rewrite configured in IIS and following is the web.config file that sits next to index.html

<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <rule name="AngularJS Routes" stopProcessing="true">
          <match url=".*" />
          <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
          </conditions>
          <action type="Rewrite" url="/MyApp/" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>

following is my main app routing which basically has entry points to different modules with it's own routes:

@NgModule({
  imports: [
    RouterModule.forRoot([
      { path: 'vm', redirectTo: 'vm/vehicles', pathMatch: 'full' },
      { path: 'rp', redirectTo: 'rp/gantt', pathMatch: 'full' },
      { path: '', redirectTo: 'rp/gantt', pathMatch: 'full' },
      { path: '404', component: PageNotFoundComponent },
      { path: '**', redirectTo: '404' }
    ]
    )
  ],
  exports: [
    RouterModule
  ]
})
export class AppRoutingModule { }

The problem is if I access the app with this url http://localhost:8181/MyApp/vm the app loads fine but the <router-outlet></router-outlet> which has to render the component configured against vm/vehicles doesn't load and it shows me 404 component inside the <router-outlet> and the url changes to http://localhost:8181/MyApp/404.

Following is the routes for vm module:

const moduleName = 'vm';

const routes: Route[] = [
      { path: 'vehicles', component: VehicleComponent },
      { path: 'standards', component: StandardsComponent }
    ];

 routes.forEach((item) => {
      item.path = moduleName + '/' + item.path;
  });

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

Solution

  • The problem was actually this part of the code:

     routes.forEach((item) => {
          item.path = moduleName + '/' + item.path;
      });
    

    I don't know the exact reason because we are only changing the path dynamically but angular doesn't accept it, the following code worked:

    const routes: Route[] = [
          { path: 'vm/vehicles', component: VehicleComponent },
          { path: 'vm/standards', component: StandardsComponent }
        ];