When migrating from AngularJS (1.x) to Angular (2+), routing conflicts often arise due to fundamental differences between UI-Router (AngularJS) and Angular Router (Angular 2+).
This guide explains:
Why routing breaks after migration
Common routing conflicts and errors
Step-by-step solutions for fixing routing issues
1. Why Routing Breaks After Migration?
AngularJS and Angular have different routing architectures:
Feature | AngularJS (UI-Router) | Angular (Angular Router) |
---|---|---|
Routing Library | angular-ui-router | @angular/router |
State-Based Routing | Uses states instead of URLs | Uses Routes for URL-based navigation |
Syntax | $stateProvider.state() | RouterModule.forRoot([]) |
Nested Views | ui-view | router-outlet |
Dynamic Parameters | $stateParams | ActivatedRoute |
Because of these differences, conflicts occur when migrating from AngularJS to Angular.
2. Common Routing Errors After Migration
1. UI-Router Not Working in Hybrid App
Error:
After upgrading, the UI-Router states stop working, and navigation breaks.
Issue:
- UI-Router (
$stateProvider
) conflicts with Angular Router (RouterModule
).
Solution:
- Use ngUpgrade to run both routers temporarily during migration.
- Install
@uirouter/angular-hybrid
and configure it.
Fix:
1️⃣ Install UI-Router Hybrid:
npm install @uirouter/angular-hybrid
2️⃣ Update app.module.ts
:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { UpgradeModule } from '@angular/upgrade/static';
import { UIRouterUpgradeModule } from '@uirouter/angular-hybrid';
@NgModule({
imports: [
BrowserModule,
UpgradeModule,
UIRouterUpgradeModule.forRoot({ states: [] }),
],
})
export class AppModule { }
3️⃣ Use uirouter
instead of Angular Router until the full migration is done.
2. ui-view
Not Working in Angular
Error:
Angular components do not load inside <ui-view>
.
🔴 Issue:
- Angular uses
<router-outlet>
instead of<ui-view>
.
Solution:
- Replace
<ui-view>
with<router-outlet>
. - Ensure routes are defined in
app-routing.module.ts
.
Fix:
1️⃣ Update HTML:
<!-- Change this -->
<ui-view></ui-view>
<!-- To this -->
<router-outlet></router-outlet>
2️⃣ Define Routes in Angular:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';
const routes: Routes = [
{ path: '', component: HomeComponent },
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
Now, components will load correctly using Angular Router.
3. $stateParams
Not Working (Dynamic Parameters)
Error:
State parameters ($stateParams
) do not get passed after migration.
Issue:
- Angular uses
ActivatedRoute
instead of$stateParams
.
Solution:
- Replace
$stateParams
withActivatedRoute
.
Fix:
1️⃣ AngularJS Code:
app.controller('DetailCtrl', function($stateParams) {
console.log('ID:', $stateParams.id);
});
2️⃣ Converted Angular Code:
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-detail',
templateUrl: './detail.component.html',
})
export class DetailComponent implements OnInit {
id: string;
constructor(private route: ActivatedRoute) {}
ngOnInit() {
this.id = this.route.snapshot.paramMap.get('id');
console.log('ID:', this.id);
}
}
Now, dynamic parameters work correctly in Angular.
4. Route Redirection Not Working
Error:
The app fails to redirect to a default route.
Issue:
- AngularJS uses
$urlRouterProvider.otherwise('/')
, while Angular uses{ path: '**', redirectTo: '/' }
.
Solution:
- Convert
$urlRouterProvider.otherwise()
to Angular’s wildcard route.
Fix:
1️⃣ AngularJS Code:
$urlRouterProvider.otherwise('/home');
2️⃣ Converted Angular Code:
const routes: Routes = [
{ path: 'home', component: HomeComponent },
{ path: '**', redirectTo: 'home' },
];
Now, undefined routes redirect properly.
5. Nested Views Not Working
Error:
Nested views (child states
) do not load correctly after migration.
Issue:
- AngularJS used named views inside
ui-view
, while Angular uses child routes.
Solution:
- Convert nested views to child routes in Angular.
Fix:
1️⃣ AngularJS Nested View:
$stateProvider
.state('dashboard', {
url: '/dashboard',
templateUrl: 'dashboard.html',
})
.state('dashboard.profile', {
url: '/profile',
templateUrl: 'profile.html',
});
2️⃣ Converted Angular Child Routes:
const routes: Routes = [
{
path: 'dashboard',
component: DashboardComponent,
children: [
{ path: 'profile', component: ProfileComponent }
]
}
];
Now, child routes work correctly.