1

I implemented a route resolver but the entire target component (events-list.component.ts) is not shown in the browser. I only see the navbar. As shown below, the resolver gets the list of events from the events service. And no errors are shown in the Chrome developer tools console. I also tried loading the app in the Firefox browser, but the problem still persists. What could be wrong with my code? Thanks.

routes.ts file

The 'events' route is the default route which I am having the problem with.

import {Routes} from '@angular/router';
import { EventDetailsComponent } from './events/event-details/event-details.component';
import { EventsListComponent } from './events/events-list.component';
import { CreateEventComponent } from './events/create-event.component';
import { Error404Component } from './errors/404.guard';
import { EventRouteActivator } from './events/event-details/event-route-activator.service';
import { EventListResolver } from './events/event-list-resolver.service';

export const appRoutes: Routes = [

    {path: 'events/new', component: CreateEventComponent, canDeactivate: ['canDeactivateCreateEvent']},
    {path: 'events', component: EventsListComponent, resolve: {events: EventListResolver}},
    {path: 'events/:id', component: EventDetailsComponent, canActivate: [EventRouteActivator]},
    {path: '404', component: Error404Component},
    {path: '', redirectTo: 'events', pathMatch: 'full'}
]

event.service.ts file

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class EventService {

  constructor() { }

  events = [
    {
      id: 1,
      name: 'Angular Connect',
      date: '9/26/2036',
      time: '10:00 am',
      price: 599.99,
      imageUrl: '/assets/images/angularconnect-shield.png',
      onlineUrl: 'http://ng-nl.org/'
     },

    {
      id: 2,
      name: 'ng-nl',
      date: '4/15/2037',
      time: '9:00 am',
      price: 950.00,
      imageUrl: '/assets/images/ng-nl.png',
      location: {
        address: 'The NG-NL Convention Center & Scuba Shop',
        city: 'Amsterdam',
        country: 'Netherlands'
      }
}
  ];

  getEvents(){
    let subject = new Subject();
    setTimeout(() => {subject.next(this.events); subject.complete;}, 2000)
    return subject;
  }

  getEvent(id: number){
  return this.events.find(event => event.id === id);
  }
}

resolver.service.ts file

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

@Injectable({
    providedIn: 'root'
})

export class EventListResolver implements Resolve<any>{

    constructor(private eventService: EventService){

    }

    resolve() { 
        return this.eventService.getEvents().pipe(map(events => events));
    }

}

event-list.component.ts file

import { Component, OnInit } from '@angular/core';
import { EventService } from '../shared/event.service';
import { ToastrService } from '../shared/toastr.service';
import { ActivatedRoute } from '@angular/router';

@Component({
  templateUrl: './events-list.component.html',
  styleUrls: ['./events-list.component.css']
})
export class EventsListComponent implements OnInit {

  events: any[];

  constructor(private eventService: EventService, private toastrService: ToastrService, private route: ActivatedRoute) { }

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

  handleThumbnailClick(eventName){
  this.toastrService.success(eventName)
  }
}

events-list.component.html

<div>
    <h1>Upcoming angular events</h1>
    <hr>
    <div class="row">
      <div class="col-md-5" *ngFor="let event of events" >
        <event-thumbnail [event]="event" (click)="handleThumbnailClick(event.name)"></event-thumbnail>
      </div>
    </div>
  </div>

I don't even see the h1 tag's text "Upcoming angular events". I only see the navbar and then the rest of the page is blank.

events-app.component.ts file (main bootstrapped component)

import { Component } from '@angular/core';

@Component({
  selector: 'events-app',
  template: `<nav-bar></nav-bar>
  <router-outlet></router-outlet>`,
  //styleUrls: ['./app.component.css']
})
export class EventsAppComponent {
  title = 'ng-fundamentals';
}
Raj Narayanan
  • 2,443
  • 4
  • 24
  • 43
  • since you dont see the

    tag, **event-list.component** itself is not instantiated(since not routed to that component). The route resolver probably is not returning proper observable/promise

    – Uday Vunnam Jul 05 '19 at 02:21

2 Answers2

1

Although you have not shared your template but I am assuming that you are trying to render the events of your component. If my understanding is correct then you are not assigning events from the route data. You should do the following -

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

The problem is in getEvents() method. You are returning subject even before the subject.next() emits the value and meantime your resolver will resolve before 2 seconds and resolver will return empty events.

Let's change the getEvents() method like this -

getEvents() {
  return of(this.events).pipe(delay(2000))
}
user2216584
  • 5,387
  • 3
  • 22
  • 29
1

Since you dont even see the static <h1> tag, event-list.component itself is not instantiated(since not routed to that component). The route resolver probably is not returning proper observable/promise

can you try with below code -

event.service.ts

getEvents(){
  return of(this.events).pipe(delay(2000)); //if you need delay
}

resolver.service.ts

resolve(){
  return this.eventService.getEvents();
}

and debug in event-list.component.ts ngOnInit, whether the events data is resolved

Uday Vunnam
  • 337
  • 2
  • 5
  • You have to import those methods from rxjs - `import { of } from 'rxjs';` `import { delay } from 'rxjs/operators';` – Uday Vunnam Jul 05 '19 at 02:34
  • 1
    I tried adding the imports but for some reason it was saying it couldn't find the operators, but I just let vs code auto import it and the resolver is working now. Thanks! :) – Raj Narayanan Jul 05 '19 at 02:37