I have this router resolver to retrieve data from the Google Firestore. I am trying to use the Resolver to fetch the data ahead. When I place debugger at resolve function it shows me the data retrieved from the Server. But it is never returning from the resolve() method. Can anyone please help me out.
Routing Module
const routes: Routes = [
{ path: '', component: HomeComponent},
{ path: 'projects', component: ProjectsComponent, resolve: {projectData: ProjectResolver} },
{ path: 'about', component: AboutComponent}
];
App Module
providers: [
ProjectService,
ProjectResolver
],
Resolver Service
import { Observable } from 'rxjs';
import { ActivatedRouteSnapshot, RouterStateSnapshot, Resolve } from '@angular/router';
import { Injectable } from '@angular/core';
import { ProjectService } from './project.service';
import { map } from "rxjs/operators";
import { Project } from './project.model';
@Injectable()
export class ProjectResolver implements Resolve<Project[]> {
constructor(private projectService: ProjectService ) {
}
resolve(route: ActivatedRouteSnapshot, router: RouterStateSnapshot) : Observable<Project[]> | any{
return this.projectService.getProjects().pipe(map(project => {
return project //Debugger shows fetched data(Array of projects)
}
));
}
}
Project Service
import { AngularFirestore } from 'angularfire2/firestore';
import { Observable } from "rxjs";
import { Injectable } from "@angular/core";
@Injectable()
export class ProjectService {
constructor(private db: AngularFirestore) {}
getProjects(): Observable<any> {
return this.db.collection('currentProjects').valueChanges();
}
}
** Project Component (This component in never loaded by Resolver )**
import { Component, OnInit, Injectable } from '@angular/core';
import { Project } from './project.model';
import { ActivatedRoute } from '@angular/router';
import { ProjectService } from './project.service';
import { Observable } from 'rxjs';
@Component({
selector: 'app-projects',
templateUrl: './projects.component.html',
styleUrls: ['./projects.component.css']
})
export class ProjectsComponent implements OnInit {
projects: Project[] = [];
constructor(private route: ActivatedRoute, private projectService: ProjectService) {
}
ngOnInit() {
this.route.data.subscribe((data: Project[]) => {
this.projects = data['projectData'];
})
}
}
The problem is that the Angular Firebase Observable(event stream) will never complete like normal "observable" so it is never resolving. I modified the Observable with the "take" operator to get the first item and forced to complete.
this.db.collection('currentProjects').valueChanges().take(1);
Changes:
I posted the solution to my problem below:
Project Resolver (Working)
export class ProjectResolver implements Resolve<any> {
constructor(private db: AngularFirestore) {
}
resolve(route: ActivatedRouteSnapshot, router: RouterStateSnapshot) : any{
return Observable.from(this.db.collection('currentProjects').valueChanges()
.do(data => {
return data
}).take(1))
}
}
Project Component(Working)
export class ProjectsComponent implements OnInit {
private projects: Project[];
constructor(private route: ActivatedRoute) {
}
ngOnInit() {
this.route.data.subscribe((data) => {
this.projects = data['projectData'];
})
}
}