reactjs - Angular2 shared observable -
doing experimentation angular2 , curious how solve situation service exposes shared observable. 1 component responsible getting data , responsible displaying data. here code:
the common httpservice responsible getting data
import { injectable } '@angular/core'; import { http, response } '@angular/http'; import { observable } 'rxjs/observable'; import { subject } 'rxjs/subject'; import 'rxjs/add/operator/map'; import 'rxjs/add/operator/catch'; @injectable() export class service { subject = new subject<string[]>; observable$ = this.subject.asobservable(); constructor(private http: http) {} observable: observable<string[]>; get(link: string): observable<string[]> { this.observable$ = this.http.get('myapi.com') .map((res: response) => this.subject.next(res.json()) .catch(this.handleerror); return this.observable$; } /** * handle http error */ private handleerror (error: any) { // in real world app, might use remote logging infrastructure // we'd dig deeper error better message let errmsg = (error.message) ? error.message : error.status ? `${error.status} - ${error.statustext}` : 'server error'; console.error(errmsg); // log console instead return observable.throw(errmsg); } }
the getcomponent responsible getting data
import { component, oninit, ondestroy } '@angular/core'; import { service } '../shared/index'; @component({ moduleid: module.id, selector: 'get', templateurl: 'get.component.html', providers: [service], }) export class getcomponent { constructor(public service: service) {} submit() { this.service.get(this.url).subscribe(); } }
the displaycomponent responsible displaying data
import { component, oninit, ondestroy } '@angular/core'; import { subscription } 'rxjs/subscription'; @component({ moduleid: module.id, selector: 'display', templateurl: 'display.component.html' }) export class displaycomponent { subscription: subscription; constructor(public service: service) {} ngoninit() { // observable undefined :( this.subscription = this.service.observable$.subscribe(data => { console.log(data); }, error => { // never gets reached :( }) } ngondestroy() { // prevent memory leak when component destroyed this.subscription.unsubscribe(); } }
this design works ok except error handling not work displaycomponent
. map function in httpservice
doesn't seem quite right this.subject.next(res.json()
also doesn't seem quite right getcomponent has "subscribe" this.service.get(this.url).subscribe();
what proper way design sort of thing? how can displaycomponent
observe errors thrown httpcomponent
your code has several problems service.$observable modified several times:
observable$ = this.subject.asobservable(); this.observable$ = this.http.get('myapi.com') .... // remove line
the right way this: get component
calls service
data. after data loaded, get component
emits data ready
event data. display component
, , other components use data, listen dataready
event , update data when event emitted.
code explain answer:
@injectable() export class getservice { /// subject subject = new subject<string[]>() /// observable observable = this.subject.asobservable() constructor(private $http: http) { } /// data getdata() { // not override observable here this.$http.get("api.com") .map(response => response.json()) // map data .subscribe((data: string[]) => this.subject.next(data), // emit data event error => this.subject.error(error)) // emit error event } }
Comments
Post a Comment