Search code examples
angularangular2-observables

Angular2 observables vs. promises


I am currently developing a web-application which has to load a set of data from a SQL-Database (like some employees or workplans). Everytime when you get routed to a component and if you update the data it will be sent to the server and returns some kind of success or error message.

At the moment I use observables but they don't behave like I want. I subscribe to an observable, receive my data and unsubscribe (I am also not sure where to unsubscribe. In the onDestroy or in the Complete part of my sub?). But somehow it is still asynchronous as the code execution continues before receiving all the data which causes failures in my application.

Here is an example of my implementation:

Employee Component:

getEmployees(department: any){

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

    this.selectedDepartment = this.ccs.getSelectedDepartment();
    //Does the same type of request as getEmployees()
    this.getDepartments();
    this.paramSub = this.route.params.subscribe(
        //Success    
        params => {    
            //doStuff
            }
        },
        //Error
        err => this.logger.error(err),
        //Complete
        () => {}
    );
}
  ngOnDestroy(){
      this.employeesSub.unsubscribe();
      this.paramSub.unsubscribe();
  }

Employee Service:

getEmployees(department: string): Observable<Employee[]>{
    let method = "getEmployees";
    let body = JSON.stringify({method, department});
    this.logger.log(body);
    let headers = new Headers({ 'Content-Type': 'application/json' });
    let options = new RequestOptions({ headers: headers });

    return this.http.post(this.url, body, options)
                    .map((res:Response) =>{ 
                            this.logger.log(res.json());
                            return res.json();
                    }).catch(this.handleError);
}

I know this may have been asked often here. But I am really unsure about the difference even if I read more and more posts I won't get it. Could someone take some time and help me?


Solution

  • Unsubscribing is a bit redundant because the observable returned from this._http.xxx() closes after the first event, which causes the subscription to become cancelled anyway.

    To ensure that on your side, you can also use this._http.xxx().first().subscribe(...). This way the subscription is closed after the first event no matter how many events the sender intends to emit.

    That code execution continues without waiting for a response is the nature of async execution and quite similar using promise or observable.

    If you want code to be executed after data arrived you have to move that code into subscribe(...), map(...) or some other observable operator.