Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to "chain" two seperate observables in Angular 2

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?

like image 684
moessi774 Avatar asked Aug 10 '16 10:08

moessi774


1 Answers

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];
  });
like image 59
Thierry Templier Avatar answered Nov 15 '22 08:11

Thierry Templier