Search code examples
angularrxjsangular-servicesbehaviorsubject

Angularjs Services implemented with Observables on Multicomponent View


currently I'm having trouble in Angular implementing Observables in a service which will be used by various components. I'm having a problem which basically is I have component A and component B inside component C (Tab style). Component A is to create an object let's say wheels and component B is for creating a car which uses a drop down to select which wheel from component A. My problem is that when I create a wheel, I have to refresh the page for the newly created wheel to appear on the drop down from component B, which is why I'm trying to implement Observables but so far I haven't had success.

Service:

constructor(private http: Http) {
    this._departamentos = <BehaviorSubject<Departamento[]>>new BehaviorSubject([]);
    this.departamentos = this._departamentos.asObservable();
  }

    private url: string = 'http://localhost:8080/';
  departamentos: Observable<Departamento[]>;
  private _departamentos: BehaviorSubject<any[]>;

    // <------------------------ GET ------------------------>
    getDepartments(): Observable<Departamento[]>{
        this.departamentos = this.http.get(this.url+'selectdepartamentos')
          .map(this.extractData)
          .catch(this.handleError);
    return this.departamentos;
  }

  private extractData(response: Response) {
      let body = response.json();
      return body || {};
  }

  private handleError(error: Response) {
      console.log(error);
      return Observable.throw(error.json().error || "500 internal server error");
  }

  // <------------------------ ADD ------------------------>
  addDepartment(newDepartment){
    return this.http.post(this.url + 'departamento', newDepartment).map(
      response => this._departamentos.next(Object.assign({}, newDepartment)) );
  }

    // <------------------------ UPDATE ------------------------>
    updateDepartment(nameOldDepartment, newDepartment){
        return this.http.put(this.url+'update/'+nameOldDepartment+'/departamento', newDepartment);
    }

    // <------------------------ DELETE ------------------------>
    deleteDepartment(nameOldDepartment){
        return this.http.delete(this.url+'delete/'+nameOldDepartment);
    }

Subscribing in the components:

this.departamentoService.getDepartments()
  .subscribe( departments => this.arregloDepartamentos = departments,
              error => this.errorMessage = <any>error);

Worth mentioning that I can initially get the values from my Component B when I refresh the page, but even though I have on my Add method(in the service) the function next on the observable, when I add nothing happens even though the object is inserted in the DB.

Any help is really appreciated, thanks in advance.


Solution

  • This is how I ended implementing it:

    Service:

    private departmentsSubject = new BehaviorSubject([]);
    private departments: Departamento[];
    
    // <------------------------ GET ------------------------>
    getDepartments(): Observable<Departamento[]>{
        return this.departmentsSubject.asObservable();
    }
    private extractData(response: Response) {
      let body = response.json();
      return body || {};
    }
    private handleError(error: Response) {
      console.log(error);
      return Observable.throw(error.json().error || "500 internal server error");
    }
    loadDepartments(){
       var sub = this.http.get(this.url+'selectdepartamentos')
          .map(this.extractData)
          .catch(this.handleError);
      sub.subscribe(
         data => this.departments = data,
         err => console.log(err),
         () => this.refresh()
      );
    }
    private refresh() {
       this.departmentsSubject.next(this.departments);
    }
    

    Component.ts:

    this.departamentoService.getDepartments().subscribe(
      departments => this.arregloDepartamentosDelete = departments
    );
    this.departamentoService.loadDepartments();