Codementor Events

Prefetch Component Data using Resolve route guard in Angular 4

Published Oct 31, 2017Last updated Nov 02, 2017

One of the basic usage of Angular router is to map the url that the user enters to that of the component. In addition to this mapping, router can be utilized to :
-Restrict the user from navigating to or away from a component before certain actions are performed,
-To do prefetching of data needed for the component before the component loads,etc.,
In this article, I am sharing how to fix the problem of component getting loaded and then the service returns the response to be displayed by the component. We will come across this scenario often as the api request for fetching data may take few seconds, though components loads instantly. This could give a bad user experience.
Here is the code example to demo the usage of Resolve route guard:
Step 1 - Implement the service :
event.service.ts

import { Injectable, EventEmitter } from '@angular/core';
import { Subject, Observable} from 'rxjs/RX';
import { IEvent } from './event.model';
@Injectable()
export class EventService {
       getEvents(): Observable<IEvent[]>{
        let subject = new Subject<IEvent[]>();
        setTimeout(() => { subject.next(EVENTS), subject.complete(); }, 100);
        return subject;
    }
   
const EVENTS : IEvent[] = [{
    id: 1,
    name: 'Angular Connect',
    date: new Date('9/26/2036'),
    time: '10:00 am'
},
    {
        id: 2,
        name: 'ng-nl',
        date: new Date('4/15/2037'),
        time: '9:00 am',
     }
 ]

Step 2 - Implement your Component class :
event-list.component.ts

import { Component, OnInit } from '@angular/core';
import {EventService, IEvent } from './shared/index';

@Component({
    templateUrl: `app/events/event-list.component.html`
})
export class EventListComponent implements OnInit {
    events: IEvent[];
     constructor(
         private eventService: EventService) {
     }

     ngOnInit() {
         //code that get data from event service
     }
}

Step 3 - Write a service to pre fetch the data:
event-list-resolver.service.ts

import {Injectable} from '@angular/core';
import { Resolve } from '@angular/router';
import { EventService } from './shared/event.service';

@Injectable()
export class EventListResolver implements Resolve<any> {
    constructor(private eventService: EventService) {
    }
    resolve() {
        return this.eventService.getEvents().map(events => events);
    }
}

Step 4 - Add Resolve route guard to your route.ts :
route.ts

import { Routes} from '@angular/router'

import {
    EventListComponent,
    EventListResolver,
 } from './events/index';

export const appRoutes = [
   { path: 'events', component: EventListComponent, resolve: { events: EventListResolver }},
 ...
    ]

Step 5 - Modify your Component class to use data from the route parameter:
event-list.component.ts

> import {ActivatedRoute} from '@angular/router';

@Component({
    templateUrl: `app/events/event-list.component.html`
})
export class EventListComponent implements OnInit {
    events: IEvent[];
     constructor(private route: ActivatedRoute) {       
    }

     ngOnInit() {
         this.events = this.route.snapshot.data['events'];
     }
}

The this.route.snapshot.data['events'], it is same name as given in the route.ts file to the data return by the resolver.

Discover and read more posts from Sharmila K
get started
post commentsBe the first to share your opinion
Show more replies