I have a component where a user chooses a report type to generate.
The component.ts function is like so:
generateReport(reportType, projectReport) {
this.showSpinner = true;
if(reportType === 'project-weekly-report')
this.router.navigate(['/weeklyReport', projectReport]).catch<any>(this.handleError.bind(this));
else this.router.navigate(['/monthlyReport']).catch<any>(this.handleError.bind(this));
}
This route it forwards to has a component that uses a resolver to handle the loading of the report. The ngOnInit() of the component looks like this:
ngOnInit(): void {
this.report = this.route.snapshot.data['projectWeeklyReport'].result;
}
The resolver looks like this:
@Injectable()
export class ProjectWeeklyReportResolve implements Resolve<any> {
constructor(private reportService: ReportService, private http: HttpClient) {}
resolve(route: ActivatedRouteSnapshot) {
return this.reportService.getProjectWeeklyReport(route.paramMap.get('projectName'));
}
}
This resolver calls the following function in the service:
getProjectWeeklyReport(projectName) {
var workerUrl = this.reportUrl + '/weeklyreport/projectname/' + projectName + '/job/';
return this.http
.get<any>(this.reportUrl + '/weeklyreport/projectname/' + projectName, this.getAuthOptions(true))
.pipe(
switchMap(workerId => this.pollFor(workerId, isWorkerCompleted, isWorkerFailed, 2000, workerUrl)),
catchError(this.handleError)
);
}
This method hits the server to tell it to start generating the report. As the report takes some time to generate, this the job has been hived off to a worker job. We then poll this worker job to check if the report has completed generating the report.
The polling function looks like this:
type CustomPollOperator = (data: any, condComp: (d) => boolean, condFail: (d) => boolean, ms: number, url: string) => Observable<any>
const isWorkerCompleted = w => w.result;
const isWorkerFailed = w => w.failedReason;
//Convenience method for polling operation
pollFor: CustomPollOperator = (data, condComp, condFail, ms, url) => {
let shouldPoll = true;
return interval(ms)
.pipe(
tap(() => console.warn('polling', shouldPoll)),
takeWhile(() => shouldPoll),
switchMap(() => this.http.get<any>(url + data.id, this.getAuthOptions(true))),
tap(res => {
if(condComp(res)) {
shouldPoll = false;
}
else if(condFail(res)) {
shouldPoll = false;
throw new Error('Polling worker job failed');
}
}),
catchError(this.handleError)
)
}
Before I updated from angular 9 to 14 the resolver would receive a finished report when the switchMap and the CustomPollOperator had finished it's job.
However, after updating the Angular version, the resolver does not wait for the polling to finish, and loads the page immediately after the first request that kicks of the job.
Any ideas what is causing this problem? I use the same code elsewhere when there is not a resolver involved and it functions as it did before.
Many thanks in advance!