Callum Osborn
Callum Osborn

Reputation: 321

Resolver Angular 6

I am creating a resolver for a route of my Angular 6 application.

Currently, I make a call to an API and return the data to a component so it can render the data in the component's template.

foo.resolver.ts

@Injectable()
export class FooResolver implements Resolve<any> {

  constructor(private fooService: FooService) {}

  resolve(route: ActivatedRouteSnapshot) {   
    return this.fooService.getById(route.paramMap.get('id'));
  }
}

foo.component.ts

export class FooComponent implements OnInit {

  fooObj: any = {};

  constructor(private route: ActivatedRoute) { }

  ngOnInit() {    
    this.fooObj = this.route.snapshot.data.fooObject;    
  }
}

However, I need to change this current implementation to make a sub call to another API once getById has completed and returned a custom object to my foo.component.ts class. I have tried to edit the resolve function to reflect this requirement.

resolve(route: ActivatedRouteSnapshot) {   

    return this.FooService.getById(route.paramMap.get('id')).pipe(map(result => {

        this.fooService.getType().subscribe(results => {

            result.type = this.getObject(results, result.typeId);

        });

        return result;
    }));

private getObject(collection: any, id: number): any {
    return collection.find(e => e.id == id);
}

However, I am getting errors in the console. Regarding cannot Cannot read property 'name' of undefined. I don't think I am returing a finished Observable from the second version of the resolve function.

Upvotes: 1

Views: 881

Answers (1)

JB Nizet
JB Nizet

Reputation: 691655

The code should be

return this.FooService.getById(route.paramMap.get('id')).pipe(
  switchMap(result => 
    this.fooService.getType().pipe(
      map(results => {
        result.type = this.getObject(results, result.typeId);
        return result;
      })
    )
  )
);

Otherwise, the router gives the result to the component as soon as the first observable has emitted, without waiting for the second one.

Upvotes: 2

Related Questions