Angular Route Resolver - multiple return types?

Viewed 24

I have a component that I've defined for a route which needs 2 different pieces of data when the component initializes.

The route is configured with a resolver:

{
    path: "session/:sessionId",
    component: CaptureComponent,
    resolve:{
      session:SessionResolver
    },
    data: {
      title: "Capture Session"
    }
}

I have successfully been able to invoke my service and retrieve one of those pieces of data and provide it to my component.

This works beautifully...

@Injectable()  
export class SessionResolver implements Resolve<Session> {  
  constructor(private sessionService: SessionService) {}  
  
  resolve(route: ActivatedRouteSnapshot): Observable<Session> {  
    const sessionId:number  = route.params['sessionId'];
    return this.sessionService.getSession(sessionId);  
  }  
}

However, I want to now modify this resolver to chain an additional service call (to retrieve a Template) that requires data from the session (the templateId) that I just retrieved. I know I can chain the service calls with a switchMap like this, but this now only returns the Template. I want both the Template and the Session in my component:

@Injectable()  
export class SessionResolver implements Resolve<Template> {  
  constructor(private sessionService: SessionService) {}  
  
  resolve(route: ActivatedRouteSnapshot): Observable<Template> {  
    const sessionId:number  = route.params['sessionId'];
    return this.sessionService.getSession(sessionId)
      .pipe(
        switchMap(session => {
          const templateId = session.templateId!;
          return this.sessionService.getTemplate(templateId);
        })
      );  
  }  
}

There are 2 pieces to this that I'm unsure how to address. First, I understand that my resolver will now either have to return a different type; what type can I return to get both pieces of data?

Is there a better way to chain the two service calls so that a custom data type (an array??) can be returned? Should I define a new type that has a session and template attribute and return that type? If so, how do I take the output of both calls?

1 Answers

Well, it seems that all I needed to do was ask the question....and then I stumbled into a solution.

I think the only thing left is to define a new custom type to define the attributes of session and template since right now I've modified it to be of type any just to get it working.

This is working for me

@Injectable()  
export class SessionResolver implements Resolve<any> {  
  constructor(private sessionService: SessionService) {}  
  
  resolve(route: ActivatedRouteSnapshot): Observable<any> {  
    const sessionId:number  = route.params['sessionId'];
    return this.sessionService.getSession(sessionId)
      .pipe(
        switchMap(session => {
          const templateId = session.templateId!;
          return this.sessionService.getTemplate(templateId)
          .pipe(
            map(
              template => {
                return {
                  'session': session,
                  'template': template
                }
              }
            )
          );
        })
      );  
  }  
}
Related