MSSE SENG 5199

Course Materials for the MSSE Web Application Development Course

slidenumbers: true

Angular Routing

Marc Kapke

kapkema@gmail.com


Angular Router


Enables SPA Browser behavior


Router configuration


Route path


Component Map definition


{path: 'articles/:category/:time', component: ArticleListComponent}


Route data


{
  path: 'articles/:category/:time',
  component: ArticleListComponent,
  data: {title: 'NYT Articles'}
}


Handle redirects


{ path: '',   redirectTo: '/articles', pathMatch: 'full' }


Wildcard route


{ path: '**', component: PageNotFoundComponent }


Routes definition


const routes: Routes = [
  {
    path: 'articles/:category/:time/:id',
    component: ArticleDetailComponent,
    resolve: {
      article: ArticleDetailResolverService
    }
  },
  {
    path: 'articles/:category/:time',
    component: ArticleListComponent,
    resolve: {
      articleList: ArticleListResolverService
    }
  },
  {
   path: 'about',
   component: AboutComponent
 },
 {
   path: '',
   redirectTo: 'articles/food/7',
   pathMatch: 'full'
 },
 { path: '**', component: PageNotFoundComponent }
];


Import routes into app


Root Module example

@NgModule({
  imports: [
    RouterModule.forRoot(appRoutes)
    // other imports here
  ],
  ...
})
export class AppModule { }

Sub-module Example

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule],
  providers: [ArticleDetailResolverService, ArticleListResolverService]
})
export class ArticleRoutingModule {
}

Router outlet


Named router outlets

<router-outlet></router-outlet>
<router-outlet name="popup"></router-outlet>
{
  path: 'contact',
  component: ContactComponent,
  outlet: 'popup'
},

Router navigation


Simple Routable app template

<h1>Nyt Articles</h1>
  <nav>
    <a routerLink="/articles" routerLinkActive="active">Articles</a>
    <a routerLink="/about" routerLinkActive="active">About</a>
  </nav>
  <router-outlet></router-outlet>

Router Navigation with parameters

onSelect(artice: Article) {
    this.router.navigate(['/article', article.id]);
}

ActivatedRoute


Route guards


Guard


Guard types


Example Resolve guard

@Injectable()
export class ArticleDetailResolverService implements Resolve<Article>{
  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Article> {
    let id = route.params['id'];
    let category = route.params['category'];
    let time = route.params['time'];
    return this.articleService.getArticle(category, time, id).first()
  }

  constructor(private articleService: ArticleService) { }

}

Map Resolver to route

{
    path: 'articles/:category/:time/:id',
    component: ArticleDetailComponent,
    resolve: {
      article: ArticleDetailResolverService
    }
  },

Subscribe to resolved Observable

@Component({
  selector: 'app-article-detail',
  templateUrl: 'article-detail.component.html',
  styleUrls: ['article-detail.component.css']
})
export class ArticleDetailComponent implements OnInit {

  constructor(private route: ActivatedRoute) {
  }

  private article: Article;

  ngOnInit() {
    this.route.data
      .subscribe((data: {article: Article}) => {
        this.article = data.article;
      });
  }

}