0

I would like to fetch an async data from a server before starting to render a component. I've attempted to use a route resolver, but I cant see how it can help.

I can access the resolver data in the component via ActivatedRoute using:

ngOnInit() {
this.route.data.subscribe((data : Data) => {
  this.caseDataManager.setCase(data['casedata']);
});

The component get initialize and rendered before the async code within the "subscribe" get completed.

What is the right way to do it?

UPDATE: my resolver code:

import { Injectable } from '@angular/core'
import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'
import { Observable } from 'rxjs/Observable'
import { Server } from '../shared/server.service'

@Injectable()
export class WorkspaceResolver implements Resolve<any>  {

constructor(private server : Server) {}

resolve(route : ActivatedRouteSnapshot, state : RouterStateSnapshot) : Observable<any>  {
    return this.server.loadCase(route.params['caseid']); #loadCase is basically "return this.http.get(API_URL+'/case/'+caseid).map(resp => resp.json()"
}

}

amit
  • 2,171
  • 4
  • 31
  • 50
  • From my understanding the component shouldn't render until the Observable in your resolve guard completes. Can you post your resolve code? – LLai Jul 11 '17 at 14:06
  • @LLai is right the resolve is used in cases where you want to load data before rendering component – Rahul Singh Jul 11 '17 at 14:07
  • @LLai, this.route.data of the ActivatedRoute is an observable. so i need to subscribe to it on ngOnInit. hence, to my understanding, by the time it will get to the code under "subscribe" its already rendered. – amit Jul 11 '17 at 14:57
  • At that point, the route.data().subscribe should be instantaneous since the data was pre-rendered so there shouldn't be any issue with populating the DOM. The route.data() observable is more for if you navigate to the same page, that subscribe function will be re-ran with the new data (because ngOnit will not be reran). This is similar to the activatedRoute.params observable – LLai Jul 11 '17 at 15:25
  • I'm not 100% sure on if the DOM is fully rendered beforengOnInit. According to the docs "ngOnit Initializes the directive/component after Angular first displays the data-bound properties and sets the directive/component's input properties." so it sounds like it does but this shouldn't cause any issue. An alternative could be to wrap your component in an ngIf and toggle the rendering based on a boolean – LLai Jul 11 '17 at 15:32

2 Answers2

0

You have to subscribe to your resolve function into ngOnInit() method on your component.ts and fetch each item on component.html. So your component will fetch data from its initialization and render it.

constructor(private myService: APIService) {}

  ngOnInit() {
    this.myService.getService()
      .subscribe(response => this.data = response);
  }
Cenvinte
  • 7
  • 3
0

Your resolver looks fine. Now you need to use it in your routes like this:

path: '/some/path',
component: SomeComponent,
resolve: {
  workspace: WorkspaceResolver
}

Don't forget to provide the resolver.

Now the data is fetched before the component is displayed.

Robin Dijkhof
  • 18,665
  • 11
  • 65
  • 116