Reputation: 796
I'm using the router resolver in order to fetch my ngrx store data before the page is loaded. After inserting the resolver into my routes, the router is not generating the content I have in
<router-outlet></router-outlet>
Other routes (without the resolver) working good, and if I erase the resolver form the route the page is loading just fine.
My resolver file:
import { Injectable } from '@angular/core';
import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { Store } from '@ngrx/store';
import { MenuItem } from '../navbar/menuItem.model';
import * as fromApp from '../store/app.reducer';
@Injectable()
export class MenuItemsResolver implements Resolve<MenuItem[]> {
constructor(
private store: Store<fromApp.AppState>
) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):
Observable<MenuItem[]> | Promise<MenuItem[]> | MenuItem[]
{
return this.store.select('menuItems').pipe(
map((data: { menuItems: MenuItem[] }) => data.menuItems)
);
}
}
Routes:
const appRoutes: Routes = [
{ path: '', component: HomeComponent, resolve: {menuItems: MenuItemsResolver} },
{ path: 'portfolio', component: ProjectsComponent },
{ path: 'portfolio/:project', component: ProjectComponent },
{ path: '404', component: PageNotFoundComponent },
{ path: '**', redirectTo: '404' }
];
Subscription to route data in the HomeComponent:
this.route.data.subscribe((data: Data) => this.menuItems = data['menuItems']);
(Notice that I've tried to erase this line to check if the problem is here and It still occur)
The problem is solved only if I deleted the resolver from my routes in app-routing.module.ts
Upvotes: 3
Views: 1185
Reputation: 1880
Resolver
waits until the Observable
closes, but the state selectors do not close. You need to close the Observable
manually using the first operator, which closes the stream after the first value.
import { Injectable } from '@angular/core';
import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs';
import { map, first } from 'rxjs/operators';
import { Store } from '@ngrx/store';
import { MenuItem } from '../navbar/menuItem.model';
import * as fromApp from '../store/app.reducer';
@Injectable()
export class MenuItemsResolver implements Resolve<MenuItem[]> {
constructor(
private store: Store<fromApp.AppState>
) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):
Observable<MenuItem[]> | Promise<MenuItem[]> | MenuItem[]
{
return this.store.select('menuItems').pipe(
map((data: { menuItems: MenuItem[] }) => data.menuItems),
first()
);
}
}
Upvotes: 5