Calling several synchronous services with RxJS + Angular 4

I'm currently doing a small Angular app that will retrieve some employee info with REST calls. However, I got stuck while handling a request similar to api/department/:departmentId/employee/:employeeId. Here's the thing: On ngOnInit(), I know I need to call the DepartmentService first and then use its result to query stuff on the EmployeeService. Based on the Angular tutorial, I would normally do this with one parameter:

this.router.params.switchMap((params: Params) =>
  this.employeeService.getEmployee(+params['employeeId'])).subscribe(employee => {
    this.employee = employee;
  }
);

I've tried this, for example:

this.router.params.switchMap((params: Params) =>
  this.departmentService.getDepartmentById(+params['id'])).subscribe(department => {
    this.department = department;
    this.router.params.switchMap((params: Params) =>
      this.employeeService.getEmployee(+params['employeeId'])).subscribe(employee => {
        this.currentEmployee = employee;
        this.equipment = this.currentEmployee.equipments.find(eq => {
          return eq.employeeId === this.currentEmployee.id && eq.departmentId === this.department.id;
        });
      }
    );
  }
);

I'm not sure what's the preferred way to chain calls using Params. I've read about Defer and BindCallback, but I haven't been able to implement either successfully. Keep in mind that I would need the results from both services so that child components can use them for rendering, and preferrably handle errors from both calls (eventually they will be network calls).

Upvotes: 0

Views: 167

Answers (1)

karser
karser

Reputation: 1693

You can remove at least one subscribe:

this.route.params
    .do((params: Params) => this.params = params)
    .switchMap(() => this.departmentService.getDepartmentById(+this.params['id']))
    .do((department) => this.department = department)
    .switchMap(department => this.employeeService.getEmployee(+this.params['employeeId']))
    .subscribe(employee => {
        this.currentEmployee = employee;
        this.equipment = this.currentEmployee.equipments.find(eq => {
            return eq.employeeId === this.currentEmployee.id && eq.departmentId === this.department.id;
        });
    });

It can be simplified more using route.snapshot.params:

this.departmentService
    .getDepartmentById(+this.route.snapshot.params['id'])
    .do((department) => this.department = department)
    .switchMap(department => this.employeeService.getEmployee(+this.route.snapshot.params['employeeId']))
    .subscribe(employee => {
        this.currentEmployee = employee;
        this.equipment = this.currentEmployee.equipments.find(eq => {
            return eq.employeeId === this.currentEmployee.id && eq.departmentId === this.department.id;
        });
    });

Upvotes: 1

Related Questions