<!DOCTYPE html>
<html>
  <head>
    <title>Angular Material Plunker</title>
    
    <!-- Load common libraries -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/typescript/2.1.6/typescript.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/core-js/2.4.1/core.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/zone.js/0.7.2/zone.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.47/system.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/web-animations/2.2.2/web-animations.min.js"></script>


    <!-- Configure SystemJS -->
    <script src="systemjs.config.js"></script>

    <script>
      System
        .import('main.ts')
        .catch(console.error.bind(console));
    </script>
    
    <!-- Load the Angular Material stylesheet -->
    <link href="https://rawgit.com/angular/material2-builds/master/prebuilt-themes/indigo-pink.css" rel="stylesheet">
    <style>body { font-family: Roboto, Arial, sans-serif; margin: 0 }</style>

  </head>

  <body class="mat-app-background">
    <material-app>Loading the Angular Material App...</material-app>
  </body>

</html>

<!--
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
-->
import {Component} from '@angular/core';
import {Http} from '@angular/http'
import {bootstrap} from '@angular/platform-browser-dynamic';
import { Router } from '@angular/router';
import 'rxjs/add/operator/map'

@Component({
  selector: 'material-app',
  templateUrl: 'app.component.html'
})
export class AppComponent {
  
  private version: any;
  
  constructor(http: Http, private router: Router) {
    // Display the currently used Material 2 version.
    this.version = http
      .get('https://api.github.com/repos/angular/material2-builds/commits/HEAD')
      .map(res => res.json());
      
     this.router.navigate(['home']);
  }
  
}

/*
 Copyright 2016 Google Inc. All Rights Reserved.
 Use of this source code is governed by an MIT-style license that
 can be found in the LICENSE file at http://angular.io/license
 */
<md-toolbar color="primary" class="md-elevation-z2">
  Parallel Routing with Resolve 

  <span class="app-toolbar-filler"></span>
  <button routerLink="home" md-button>Home</button>
  <!--<button md-button-->
  <!--  [routerLink]="['/speakers', {outlets: {'list': ['speakersList'], 'bio': ['bio']}}]">-->
  <!--  Speakers-->
  <!--</button>-->
</md-toolbar>

<div class="app-content">
  <router-outlet></router-outlet>
</div>
/** Add Transpiler for Typescript */
System.config({
  transpiler: 'typescript',
  typescriptOptions: {
    emitDecoratorMetadata: true
  },
  packages: {
    '.': {
      defaultExtension: 'ts'
    },
    'vendor': {
      defaultExtension: 'js'
    }
  }
});

System.config({
  map: {
    'main': 'main.js',
    
    // Angular specific mappings.
    '@angular/core': 'https://unpkg.com/@angular/core/bundles/core.umd.js',
    '@angular/common': 'https://unpkg.com/@angular/common/bundles/common.umd.js',
    '@angular/compiler': 'https://unpkg.com/@angular/compiler/bundles/compiler.umd.js',
    '@angular/animations': "https://unpkg.com/@angular/animations/bundles/animations.umd.js",
    '@angular/animations/browser': 'https://unpkg.com/@angular/animations/bundles/animations-browser.umd.js',
    '@angular/http': 'https://unpkg.com/@angular/http/bundles/http.umd.js',
    '@angular/forms': 'https://unpkg.com/@angular/forms/bundles/forms.umd.js',
    '@angular/router': 'https://unpkg.com/@angular/router/bundles/router.umd.js',
    '@angular/platform-browser': 'https://unpkg.com/@angular/platform-browser/bundles/platform-browser.umd.js',
      '@angular/platform-browser/animations': 'https://unpkg.com/@angular/platform-browser/bundles/platform-browser-animations.umd.js',
    '@angular/platform-browser-dynamic': 'https://unpkg.com/@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
    '@angular/material': 'https://rawgit.com/angular/material2-builds/master/bundles/material.umd.js',
    '@angular/cdk': 'https://rawgit.com/angular/cdk-builds/master/bundles/cdk.umd.js',

    
    // Third party libraries
    'tslib': 'https://unpkg.com/tslib@1.7.1',
    'rxjs': 'https://unpkg.com/rxjs',
  },
  packages: {
    // Thirdparty barrels.
    'rxjs': { main: 'index' },
     app: {
      main: './main.ts',
      defaultExtension: 'ts'
    }
  },meta: {
      'typescript': {
        "exports": "ts"
      }
    }
});

/*
 Copyright 2016 Google Inc. All Rights Reserved.
 Use of this source code is governed by an MIT-style license that
 can be found in the LICENSE file at http://angular.io/license
 */
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import { BrowserModule }  from '@angular/platform-browser';
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {HttpModule} from '@angular/http';
import {AppComponent} from './app.component';
import {HomeComponent} from './home/home.component';
import {SpeakersComponent} from './speakers/speakers.component';
import {SpeakersListComponent} from './speakers/speakers-list/speakers-list.component';
import {BioComponent} from './speakers/bio/bio.component';
import { Routes, RouterModule } from '@angular/router';
import { APP_BASE_HREF } from '@angular/common';
import {PeopleResolveService} from 'people-resolve.service';
import {PlanetsResolveService} from 'planets-resolve.service';
import {MaterialModule} from '@angular/material';

@NgModule({
 
  imports: [
    BrowserModule,
    MaterialModule,
    CommonModule,
    HttpModule,
    RouterModule.forRoot(
      [
        { path: '', redirectTo: 'home', pathMatch: 'full' },
        { path: 'home', component: HomeComponent },
        { path: 'speakers', component: SpeakersComponent, 
          children: [
                { path: 'planetOne', component: SpeakersListComponent, outlet: 'planet' },
                { path: 'peopleOne', component: BioComponent ,outlet: 'people' }
      ]
    }
  ],{enableTracing : true }
  )
   
  ],
  declarations: [
    AppComponent,
    HomeComponent,
    SpeakersComponent,
    SpeakersListComponent,
    BioComponent],
  bootstrap: [AppComponent],
  providers: [
     { provide: APP_BASE_HREF, useValue: '/' },
     PeopleResolveService,
     PlanetsResolveService
  ]
})
export class PlunkerAppModule {}

platformBrowserDynamic().bootstrapModule(PlunkerAppModule);

/*
 Copyright 2016 Google Inc. All Rights Reserved.
 Use of this source code is governed by an MIT-style license that
 can be found in the LICENSE file at http://angular.io/license
 */
.card-wrapper {
  text-align: center;
}

md-card {
  max-width: 550px;
  padding: 0;
  display: inline-block;
}

md-card-content {
  padding: 0 24px 24px;
}

img {
  border-bottom: 5px solid #c2185b;
}

md-card-actions {
  margin: 0 !important;
}
<div class="card-wrapper">
  <md-card>
    <img
      width="100%"
      src="/assets/nodes.png"
      alt="">
    <md-card-content>
      <md-card-title>Welcome to Parallel Routing</md-card-title>
      <md-card-subtitle>

        click the button below.
      </md-card-subtitle>
      <md-card-actions>
        <button md-raised-button class="md-primary"
          [routerLink]="['/speakers']">
          <!--{outlets: {list: ['speakersList'], bio: ['none']}}]">-->
          Universe
        </button>
        <!--<button (click)="clickButton()">-->
        <!--  Speakers-->
        <!--</button>-->
      </md-card-actions>
    </md-card-content>
  </md-card>
</div>
import { Component } from '@angular/core';
import {Router,ActivatedRoute} from '@angular/router';

@Component({
  selector: 'app-home',
  templateUrl: 'home/home.component.html',
  styleUrls: ['home/home.component.css']
})
export class HomeComponent {
  constructor(private router: Router, private route:ActivatedRoute){
    
  }
  
  clickButton(){
    this.router.navigate([{outlets: {list: ['speakersList']}}], {relativeTo: this.route});
    // this.router.navigate('',[{outlets: bio}]);
    
    
    // this.iserveRouteService.navigateChild([{outlets: {child1: ['newiachild1', new Date().getTime()]}}], { relativeTo: this.route }); 
    
  }
  
}
.columns {
  display: flex;
  flex-direction: row;
}

md-card {
  flex: 1 1 50%;
  width: 50%;
}
<div class="row">
      <button md-raised-button class="md-error pull-left" (click)="clickPlanet()">
        Planet
      </button>

        <button md-raised-button class="md-primary pull-right" (click)="clickPeople()">
          People
        </button>
</div>

<div class="columns">

  <md-card>
    <router-outlet name="planet"></router-outlet>
  </md-card>
  <md-card>
    <router-outlet name="people"></router-outlet>
  </md-card>
</div>
import { Component } from '@angular/core';
import { SpeakersService } from './shared/speakers.service';
import {Router,ActivatedRoute} from '@angular/router';

@Component({
  selector: 'app-speakers',
  templateUrl: 'speakers/speakers.component.html',
  styleUrls: ['speakers/speakers.component.css'],
  providers: [SpeakersService]
})
export class SpeakersComponent{
  
  constructor(private router: Router, private route:ActivatedRoute){
    
  }
  
  clickPlanet(){
        //this.router.navigate(['/speakers', {outlets: {'bio': [id]}}]);

    this.router.navigate([{outlets: {planet: ['planetOne']}}
    ], {relativeTo: this.route});
   
    // this.router.navigate('',[{outlets: bio}]);
    
    
    // this.iserveRouteService.navigateChild([{outlets: {child1: ['newiachild1', new Date().getTime()]}}], { relativeTo: this.route }); 
    
  }
  
  clickPeople(){
     this.router.navigate([{outlets: {people: ['peopleOne']}}
    ], {relativeTo: this.route});
  }
  
}
md-grid-tile {
  background-size: contain;
  filter: grayscale(1);
  -webkit-filter: grayscale(1);
  cursor: pointer;

  -webkit-transition: all .3s ease-in-out;
  -moz-transition: all .3s ease-in-out;
  -ms-transition: all .3s ease-in-out;
  -o-transition: all .3s ease-in-out;
  transition: all .3s ease-in-out;

  border: 1px solid #c2185b;
}

md-grid-tile:hover {
  filter: grayscale(0);
  -webkit-filter: grayscale(0);
  -webkit-transform: scale(0.99);
  -moz-transform: scale(0.99);
  -ms-transform: scale(0.99);
  -o-transform: scale(0.99);
  transform: scale(0.99);
  z-index: 1;
  -webkit-box-shadow: inset 0 0 30px 30px rgba(0, 0, 0, 0.5);
  -moz-box-shadow: inset 0 0 30px 30px rgba(0, 0, 0, 0.5);
  box-shadow: inset 0 0 30px 30px rgba(0, 0, 0, 0.5);
}
<div *ngIf="loading">Loading...</div>
<div *ngIf="!loading">
  <md-card-title>Planet</md-card-title>
  <md-grid-list cols="3" gutterSize="4px">
    Planet Data After API Resolve Call
  </md-grid-list>
</div>
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { SpeakersService, Speaker } from '../shared/index';
import { Observable } from 'rxjs/Observable';

@Component({
    selector: 'app-speakers-list',
    templateUrl: 'speakers/speakers-list/speakers-list.component.html',
    styleUrls: ['speakers/speakers-list/speakers-list.component.css']
})
export class SpeakersListComponent implements OnInit {
    loading: boolean;
    speakers: Speaker[] = [];

    constructor(
        private router: Router,
        private service: SpeakersService
    ) { 
      this.fetchData().subscribe(() => {
        this.loading = false
      });
    }

    ngOnInit() {
        this.loading = true;
        this.speakers = this.service.getSpeakers();
    }

    showBio(id) {
        this.router.navigate(['/speakers', { outlets: { 'bio': [id] } }]);
    }

    private fetchData() {
        let obs = new Observable(observer => {
            setTimeout(() => {
                observer.next(1);
            }, 5000);
        });

        return obs;
    }
}
<!--<div *ngIf="!currentSpeaker">-->
<!--  <md-card-title>Please select a speaker</md-card-title>-->
<!--  <md-card-subtitle>No speaker selected</md-card-subtitle>-->
<!--</div>-->

<!--<md-card-title>{{currentSpeaker?.name}}</md-card-title>-->
<!--<md-card-subtitle>{{currentSpeaker?.bio}}</md-card-subtitle>-->

<div *ngIf="loading">Loading...</div>
<div *ngIf="!loading">
  <h3>People</h3>
  People After API Resolve Call
</div>
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { SpeakersService, Speaker } from '../shared/index';
import { Observable } from 'rxjs/Observable';

@Component({
  selector: 'app-bio',
  templateUrl: 'speakers/bio/bio.component.html'
  
})
export class BioComponent implements OnInit {
  currentSpeaker: Speaker;
  loading: boolean;
  constructor(
    private route: ActivatedRoute,
    private service: SpeakersService
  ) { 
    this.fetchData().subscribe(()=> {
      this.loading = false;
    });
  }

  ngOnInit() {
    this.loading = true;
    this.route.params.subscribe((params: {id: string}) => {
      this.currentSpeaker = this.service.getSpeakerByID(params.id);
    });
  }
  
  private fetchData() {
        let obs = new Observable(observer => {
          setTimeout(() => {
              observer.next(1);
          }, 5000);
        });
        
        return obs;
    }
}
import { export } from '@angular/core';

export interface Speaker {
  id: number,
  name: string,
  bio: string,
  src: string
}
import { Injectable } from '@angular/core';
import { Speaker } from './speaker';

@Injectable()
export class SpeakersService {
  
  
  
  private speakers: Speaker[] = [
    {id: 1, name: 'Luke Ruebbelke', src: 'luke.jpg', bio: 'Co-Founder of @UltimateAngular. Developer. Hacker. Community backer. Author and blogger. Console logger.'},
    {id: 2, name: 'Todd Motto', src: 'todd.jpg', bio: 'Developer Advocate @Telerik / @ProgressSW. Co-founder @UltimateAngular. Author. Developer Expert @google. Lesser half of @RachaelLPurser. @ken_wheeler advocate.'},
    {id: 3, name: 'Gleb Bahmutov', src: 'gleb.jpg', bio: 'JavaScript ninja, image processing expert, software quality fanatic'},
    {id: 4, name: 'Jeff Whelpley', src: 'jeff.jpg', bio: 'CTO @gethumancom, Google Developer Expert (GDE), Host of @AngularAir, Boston Angular Meetup Co-organizer, Boston College \'00, ♥ Red Sox'},
    {id: 5, name: 'Pascal Precht', src: 'pascal.jpg', bio: 'I like headphones, art, skateboarding and coding. Angular GDE at @Google, @thoughtram co-founder and creator of @5thingsAngular'},
    {id: 6, name: 'Victor Savkin', src: 'victor.jpg', bio: 'Mr. Rogers of JavaScript. Victor makes Angular. He also toys with eclectic programming technologies and obsesses over fonts and keyboard layouts.'}
  ];

  constructor() { }

  getSpeakers() {
    return this.speakers;
  }

  getSpeakerByID(id) {
    return this.speakers.find(speaker => speaker.id === Number(id));
  }
}
export { SpeakersService } from './speakers.service';
export { Speaker } from './speaker';
import { Injectable } from '@angular/core';
import { Resolve, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Rx';
import { Http, Response } from '@angular/http';

@Injectable()
export class PlanetsResolveService implements Resolve<any> {
  
  constructor(private http: Http){
    
  }
  
  resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<any> {
    
    return Observable.of({}).delay(5000);
    // return this.http.get('https://swapi.co/api/planets/10').map((data: Response) => data.json());

  }
}
import { Injectable } from '@angular/core';
import { Resolve, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Rx';
import { Http, Response } from '@angular/http';

@Injectable()
export class PeopleResolveService implements Resolve<any> {
  
  constructor(private http: Http){
    
  }
  
  resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<any> {
    
    return Observable.of({}).delay(5000);
    //return this.http.get('https://swapi.co/api/people/10').map((data: Response) => data.json());

  }
}

import {
  CdkDataTableModule,
  FullscreenOverlayContainer,
  MdAutocompleteModule,
  MdButtonModule,
  MdButtonToggleModule,
  MdCardModule,
  MdCheckboxModule,
  MdChipsModule,
  MdCoreModule,
  MdDatepickerModule,
  MdDialogModule,
  MdExpansionModule,
  MdGridListModule,
  MdIconModule,
  MdInputModule,
  MdListModule,
  MdMenuModule,
  MdNativeDateModule,
  MdProgressBarModule,
  MdProgressSpinnerModule,
  MdRadioModule,
  MdRippleModule,
  MdSelectModule,
  MdSidenavModule,
  MdSliderModule,
  MdSlideToggleModule,
  MdSnackBarModule,
  MdTabsModule,
  MdToolbarModule,
  MdTooltipModule,
  OverlayContainer
} from '@angular/material';
import {NgModule} from '@angular/core';

/**
 * NgModule that includes all Material modules that are required to serve 
 * the Plunker.
 */
@NgModule({
  exports: [
    MdAutocompleteModule,
    MdButtonModule,
    MdButtonToggleModule,
    MdCardModule,
    MdCheckboxModule,
    MdChipsModule,
    MdDatepickerModule,
    MdDialogModule,
    MdExpansionModule,
    MdGridListModule,
    MdIconModule,
    MdInputModule,
    MdListModule,
    MdMenuModule,
    MdCoreModule,
    MdProgressBarModule,
    MdProgressSpinnerModule,
    MdRadioModule,
    MdRippleModule,
    MdSelectModule,
    MdSidenavModule,
    MdSlideToggleModule,
    MdSliderModule,
    MdSnackBarModule,
    MdTabsModule,
    MdToolbarModule,
    MdTooltipModule,
    MdNativeDateModule,
    CdkDataTableModule,
  ]
})
export class PlunkerMaterialModule {}