moessi774 moessi774 - 19 days ago 5
TypeScript Question

How to "chain" two seperate observables in Angular 2

Hello Stackoverflow community.

This is my first post so please correct me if something is not properly done.

I am developing a web application with Angular2 and I have got some problems with getting data from the server.

import ...

@Component({
...

})
export class EmployeeManagementTableComponent implements OnInit, OnDestroy{

private employees: Employee[];
private departments: SelectItem[] = [];
private selectedDepartment: string;
private columns: any[];
private paramSub: any;
private employeesSub: any;
private departmentSub: any;


constructor(private employeeManagementService: EmployeeManagementService,
private route: ActivatedRoute,
private router: Router,
private ccs: ComponentCommunicatorService,
private logger: Logger) { }

ngOnInit(){

this.columns = [
...
];

//ccs is just a service for storing/getting app wide infomation

this.selectedDepartment = this.ccs.getSelectedDepartment();
this.getDepartments();
this.getEmployees(this.selectedDepartment);

...
}

ngOnDestroy(){
/*this.employeesSub.unsubscribe();
this.departmentDub.unsubscribe();*/
}

getDepartments(){

this.departments.push({label: 'Alle', value: 'all'});

this.departmentSub = this.employeeManagementService.getDepartments().subscribe(
data => {data.forEach((item, index) => {
this.departments.push({label: item, value: index.toString()});
});
},
err => this.logger.error(err),
() => {this.logger.log('done loading');
this.departmentSub.unsubscribe()}
);
}
getEmployees(department: any){

this.employeesSub = this.employeeManagementService.getEmployees(department).subscribe(
data => {this.employees = data},
err => this.logger.error(err),
() => {this.logger.log('done loading');
this.employeesSub.unsubscribe()}
);
}


As you see when the component gets initalized it calls two Methods for getting data. The methods get observables from my service and subscribe to them.

The problem is that order is like
call1, call2, result1, result2, ...
and I think there is something not right. It should be
call1, result1, call2, result2, ...
or am I wrong? I tried subscribing to observable2 in the
onComplete
of observable1 but I think dedicated methods would be useless then.
I have researched and found some solutions with subscribing to both observables simultaneously with concat but I just want the code to continue after getDepartments() when all data traffic is finished.

And should I unsubscribe in the
OnDestroy()
or in the
OnComplete
of the
subscribe
function I don't really get the difference?

Answer

If you want to control the execution order of observables, you need to build an asynchronous data flow leveraging operators like flatMap (execution in series) or Observable.forkJoin (execution in parallel)

Here are samples:

// Series
someObservable.flatMap(result1 => {
  return someOtherObservable;
}).subscribe(result2 => {
  (...)
  (...)
});

// Parallel
Observable.forkJoin([ someObservable, someOtherObservable ])
  .subscribe(results => {
    let result1 = results[0];
    let result2 = results[1];
  });