Angular 2 - equivalent to router resolve data for new router

8.9k views Asked by At

I am playing with Angular 2.0's new router and I try to use something similar to Angular 1.X ui-router / ng-route resolve mechanism.

I was trying to achieve this using RouteData:

import {Component, ViewEncapsulation} from 'angular2/core';
import {
  RouteConfig,
  ROUTER_DIRECTIVES
} from 'angular2/router';
// import {HTTP_PROVIDERS} from 'angular2/http';

import {HomeCmp} from '../home/home';
import {AboutCmp} from '../about/about';
import {NameList} from '../../services/name_list';
import {PersonalizationList} from '../../services/personalization_list';

@Component({
  selector: 'app',
  viewProviders: [NameList, PersonalizationList],
  templateUrl: './components/app/app.html',
  styleUrls: ['./components/app/app.css'],
  encapsulation: ViewEncapsulation.None,
  directives: [ROUTER_DIRECTIVES]
})
@RouteConfig([
  { path: '/', component: HomeCmp, as: 'Home', data: this.history },
  { path: '/about', component: AboutCmp, as: 'About' }
])
export class AppCmp {
  history: string[] = [];
  constructor(public list: PersonalizationList) {
    list.get('histoy', (response) => {
      this.history = response;
    });
  }
}

The component using this (home):

import {Component} from 'angular2/core';
import {PersonalizationList} from '../../services/personalization_list';
import {Router, ROUTER_DIRECTIVES, routerBindings, RouteConfig, RouteData} from 'angular2/router';

@Component({
  selector: 'home',
  templateUrl: './components/home/home.html',
  styleUrls: ['./components/home/home.css'],
  directives: [ROUTER_DIRECTIVES]
})
export class HomeCmp {
  constructor(data: RouteData) {
    console.log(data);
  }
}

The data logged to console is not the data I initialised from the service. If I initialise it directly in @RouteConfig, it will work. For example:

@RouteConfig([
  { path: '/', component: HomeCmp, as: 'Home', data: [1,2,3,4] },
  { path: '/about', component: AboutCmp, as: 'About' }
])

So, I'm missing the part of passing data from controller / component to @RouteConfig.

Another question - in Angular 1.X it was good practice to pass data to route via router's resolve. Is this still good practice to pass data to component this way, using the new router / components router?

Edit The solution can be found here - using the @CanActivate event

2

There are 2 answers

5
Günter Zöchbauer On BEST ANSWER

update

@Injectable()
export class CrisisDetailResolve implements Resolve<Crisis> {
  constructor(private cs: CrisisService, private router: Router) {}
  resolve(route: ActivatedRouteSnapshot): Promise<Crisis>|boolean {
    let id = route.params['id'];
    return this.cs.getCrisis(id).then(crisis => {
      if (crisis) {
        return crisis;
      } else { // id not found
        this.router.navigate(['/crisis-center']);
        return false;
      }
    });
  }
}
  children: [
  {
    path: ':id',
    component: CrisisDetailComponent,
    canDeactivate: [CanDeactivateGuard],
    resolve: {
      crisis: CrisisDetailResolve
    }
  },
ngOnInit() {
  this.route.data
    .subscribe((data: { crisis: Crisis }) => {
      this.editName = data.crisis.name;
      this.crisis = data.crisis;
    });
}

https://angular.io/docs/ts/latest/guide/router.html#!#resolve-guard

original

The new router in RC.4 got resolve added

resolve is a map of DI tokens used to look up data resolvers. See Resolve for more info.

class TeamResolver implements Resolve {
  constructor(private backend: Backend) {}
  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):Observable<any> {
    return this.backend.fetchTeam(this.route.params.id);
  }
}

bootstrap(AppComponent, [
  TeamResolver,
  provideRouter([{
    path: 'team/:id',
    component: TeamCmp,
    resolve: {
      team: TeamResolver
    }
  }])
);

See also RouterConfig

2
user3636086 On

You have to move your @RouteConfig into the AppCmp constructor:

//@RouteConfig([
//  { path: '/', component: HomeCmp, as: 'Home', data: this.history },
//  { path: '/about', component: AboutCmp, as: 'About' }
//])
export class AppCmp {
  history: string[] = [];
  constructor(public list: PersonalizationList,
              private router_: Router) {
    list.get('histoy', (response) => {
      this.history = response;
    });
    router_.config([
      { path: '/', component: HomeCmp, as: 'Home', data: this.history },
      { path: '/about', component: AboutCmp, as: 'About' }
    ]);
  }
}

On the console output I could see:

RouteData {data: "test sample"}

Hope it helps!