1

I am trying to pre-fetch data before displaying the component by using angular2's resolver.

so in my data.service.ts: I have a function that retrieves an employee detail:

  getEmployee(id:string) {
      let headers = new Headers();
      this.createAuthorizationHeader(headers);
      this.employeeUrl = 'someurl/property?'+'employee_number='+id;
      return this._http.get(this.employeeUrl, {headers})
        .map(resp => resp.json())
        .do(data => console.log('employee: ' +  JSON.stringify(data)))

//this returns a json log in console. 

In my employee-detail-resolver.service.ts file i have set up a resolver like this:

@Injectable()
export class EmployeeDetailResolver implements Resolve<IEmployee>{
  employee: IEmployee;

  constructor( private _dataService: DataService, private router: Router ) {}

  resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<IEmployee> {
    console.log('returning resolved data');
    let id = route.params['id'];
    return this._dataService.getEmployee(id)
      .map(employee => {
        if(employee) {
        return employee;
      } else {
        this.router.navigate(['/employees']);
        return null;
      }
    });

}

}

and I try to get the data from the resolver in my employee-detail.component.ts file like this:

export class EmployeeDetailComponent implements OnInit {
  busy: Subscription;
  employee: IEmployee;
  id: string;

  constructor(private route: ActivatedRoute,
              private router: Router,
              private _dataService: DataService
              ) {

    }


  ngOnInit() {
    this.route.data
      .subscribe((data: {employee: IEmployee}) => {
        this.employee = data.employee;
      })
     console.log("testing employee detail:", this.route.snapshot.data['data']);
  // this logs undefined in the console
  }

  onBack(): void {
    this.router.navigate(['/employees']);
  }
}

I know I'm getting the data accurately because I see it in the console, and my template with *ngIf="employee" loads with no data. I don't understand why my component returns undefined value..

my routing module looks like this:

const APP_ROUTES: Routes = [
    {path: 'employee/:id', component: EmployeeDetailComponent,
      resolve: {
       employee: EmployeeDetailResolver
      }
    },
    {path: 'employees', component: EmployeesListComponent},
    {path: '', redirectTo: '/employees', pathMatch: 'full' }
];

export const Routing = RouterModule.forRoot(APP_ROUTES, {useHash: true});

I have it declared as a provider in my app.module.ts:

  providers: [ DataService, EmployeeDetailResolver ],

can someone please help me understand what I am doing wrong??

FIX: in employee-detail.component.ts I changed to

  ngOnInit() {
    this.employee = this.route.snapshot.data['employee'][0];
    console.log("working?",this.employee[0]);
  }

and now the data displays every time I click! It was snapshot!!!

1 Answer 1

3

Code that depends on data from async calls needs to be executed within callbacks that are called when data arrives:

this.route.data
  .subscribe((data: {employee: IEmployee}) => {
    this.employee = data.employee;
    console.log("testing employee detail:", data['data']);

  })
  // code here is executed before async data was received
Sign up to request clarification or add additional context in comments.

6 Comments

Hi, thanks for your answer, but I have a resolver that prefetches data. In my routing module, I have the resolver defined: {path: 'employee/:id', component: EmployeeDetailComponent, resolve: { employee: EmployeeDetailResolver } }, doesn't it tell my employee-detail component that the resolver needs to resolve the data first before it can run any of its own methods?
I see what you mean. Didn't look close enough.
Actually I'd also expect route.snapshot.data to actually contain the value when the component is created, but in angular.io/docs/ts/latest/guide/router.html#!#resolve-guard they also only use this.route.data.subscribe(...)
Sorry., I don't quite get how route.snapshot.data can fix the problem...Could you show me how you would change it using route.snapshot.data?
Hi! You were actually right! snapshotworked! I changed my employee-detail.component's ngOnInit function to this: this.employee = this.route.snapshot.data['employee'][0]; and it works now!!
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.