Search code examples
angular5angular-httpclient

Angular 5 HTTPClient not returning results for RouteResolver


I have to say HttpClient Observables, subscriptions etc are pretty hard/time consuming to get right.

I have been working on a problem for a while now and tearing my hair out. I have a service that I need to be able to perform a mapping function on.

  loadAllSummary(organisationId: number) {
    return this.http.get('/api/aircrafts/organisations/' + organisationId)
      .pipe(
        map(data => data.forEach(datum => {
          console.log('why am i not getting here! ' + JSON.stringify(data));
          return this.mapToSummary(datum);
        }))
      );
  }

with the mapToSummary() method:

  private mapToSummary(aircraft: Aircraft): IAircraftSummary {
    const lastDate: Date = new Date(Math.max.apply(null, aircraft.workorders.map(function(e) {
      return new Date(e.date);
    })));

    return new AircraftSummary({
      lastWork: lastDate,
      rego: aircraft.registration,
      make: aircraft.make,
      model: aircraft.model,
      contact: (aircraft.owner.type.endsWith('primary')) ? aircraft.owner.principal : aircraft.operator.principal,
      phone: (aircraft.owner.type.endsWith('primary')) ? aircraft.owner.contact.phone : aircraft.operator.contact.phone
    });
  }

Now, I need these summaries as input data to a view, so I borrowed code from the interwebs and created this ResolverService:

@Injectable()
export class AircraftsResolverService implements Resolve<IAircraftSummary[]> {

  constructor(private service: AircraftService,
              private router: Router) { }

  resolve(route: ActivatedRouteSnapshot,
          state: RouterStateSnapshot): Observable<IAircraftSummary[]> {
    console.log('called AircraftsResolverService')
    const id = route.params['id'];
    if (isNaN(+id)) {
      console.log(`Organisation id was not a number: ${id}`);
      this.router.navigate(['/login']);
      return Observable.of(null);
    }
    return this.service.loadAllSummary(+id)
      .map(summaries => {
        console.log(summaries)
        if (summaries) {
          return summaries;
        }
        console.log(`Summaries were not found: ${id}`);
        this.router.navigate(['/organisations/', +id]);
        return null;
      })
      .catch(error => {
        console.log(`Retrieval error: ${error}`);
        this.router.navigate(['/organisations/', +id]);
        return Observable.of(null);
      });
  }
}

Which I then refer to in the ngOnInit call...

ngOnInit() {

this.currentUser = this.authenticationService.returnCurrentUser();

this.route.data
  .subscribe(({aircrafts}) => {
    this.aircrafts = aircrafts;

    const id = +this.route.snapshot.paramMap.get('id');
    console.log(' where are my aircraft!' + JSON.stringify(aircrafts));
    this.ELEMENT_DATA = aircrafts;
    this.displayedColumns = ['Last Work', 'Rego', 'Make', 'Model', 'Contact', 'Phone'];
    this.dataSource = new MatTableDataSource(this.ELEMENT_DATA);
    this.dataSource.sort = this.sort;
    console.log(id);
    if (id) {
      this.organisationService.getById(id).subscribe(org => {
        this.organisation = org;
      });
    } else {
      console.log('its bad');
    }

  });

console.log(this.dataSource);

}

The console log under the subscribe is undefined and the console.logs under the service never get triggered. So once again, I find myself not understanding why subscription fire or not fire, or whatever it is that they do.

How do I get past this? thanks everyone.

EDIT: appears that the problem is actually in the ResolverService, I have been able to determine that the data service is getting the results and that they are correct. For some reason, the resolver service can't see them.


Solution

  • The answer was in the route resolver, or rather the app-routing-module. I should have included it in the question, because some of the angular saltys would have picked it up

    I was trying to do this:.

      { path: 'organisations/:orgId/aircrafts/:id', component: AircraftsComponent, resolve: {aircrafts : AircraftsResolverService}, canActivate: [AuthGuard] },
    

    But you can't, you have to do this:

      { path: 'organisations/aircrafts/:orgId/:id', component: AircraftsComponent, resolve: {aircrafts : AircraftsResolverService}, canActivate: [AuthGuard] },
    

    results in very non-resty urls, but, hey, whatever works, right?