2017-06-15 18 views
2
でrxjs BehaviorSubject使用量が

マイサービスコードは、下記のようになります -アンギュラ4 - サービス

のDataService

@Injectable() 
export class DataService { 
... 
private serviceRequestDtoSource = new BehaviorSubject<ServiceRequestDto>(null); 
serviceRequestDto$ = this.serviceRequestDtoSource.asObservable(); 
... 
getAccountInfo(serviceRequestDto : ServiceRequestDto){ 
    let body = JSON.stringify(serviceRequestDto); 
    let headers = new Headers({ 
     'Content-Type': 'application/json' 
    }); 
    let options = new RequestOptions({ headers: headers }); 
    console.log("In data service.getAccountInfo"); 
    this.http 
     .post(this.clientAccountInfoURL, body, options) 
     .map((response : Response) => { return <AccountDto[]> response.json().accountDtoList}) 
     .do(data=> console.log('All :'+ JSON.stringify(data))) 
     .subscribe(response => { 
          this.accountList = response; 
          this.serviceRequestDto.accountDtoList = this.accountList; 
          this.serviceRequestDtoSource.next(serviceRequestDto); 
         }, 
         error => this.errorMessage = <any>error); 
} 

(サービスの上に当たっても、サブスクライブ)検索コンポーネントは、以下のようになります -

上述したように、制御はコンポーネントの内部subscribeメソッドはログのどれも印刷されないので、私は適切な方法でBehaviorSubjectを使用しているかどうかは確かです。

は、私は次のリンクをたどるしようとした -

Angular 2 - Behavior Subject vs Observable? - >ここに述べたようにサブスクライブに入るわけではありません。
http-observables - >私はこの方法を試したとき、それは購読入るが、その後ログのエラーをスローしない -

cannot read property xyz of null as component logs gets printed even before i get data from service.Service logs got printed later after i got above mentioned error.

私の意図は、サービスを打つSearchComponent自体からBehaviorSubjectに加入することではありません。私はサービスからの値をコンポーネントで取得するかどうかをテストしようとしています。serviceRequestDtoの値は、すべてのコンポーネントから同じままです。

アップデート1:

Iブランドンによって示唆されるように(1)ReplaySubjectを使用しようとしたが、コンポーネントとする対象に加入しながら、まだ私は、エラーの下になっていました。

私の更新 サービスコードは次のようになります

TypeError: Cannot read property 'name' of undefined(…)

-

serviceRequestDtoSource = new ReplaySubject<ServiceRequestDto>(1); 
getAccountInfo(serviceRequestDto : ServiceRequestDto){ 
... 
//Logic same as earlier 
//I'm getting all values from service here in the logs I print 

} 

私はサービスコードに次の使用していた以前のご注意 -

private serviceRequestDtoSource = new BehaviorSubject<ServiceRequestDto>(null); 
serviceRequestDto$ = this.serviceRequestDtoSource.asObservable(); 

私の更新検索コンポーネントコードはこのようです -

this.dataService.getAccountInfo(this.serviceRequestDto); 
this.dataService.serviceRequestDtoSource.subscribe((serviceRequestDtoValue : ServiceRequestDto) => { 
this.serviceRequestDto = serviceRequestDtoValue; 
console.log('search.serviceRequestDto.length:'+this.serviceRequestDto.accountDtoList.length);   
// prints 'search.serviceRequestDto.length:0' 
console.log('search.serviceRequestDto.accountDtoList name:'+this.serviceRequestDto.accountDtoList[0].name); // throws 'vendor.bundle.js:5764 ERROR TypeError: Cannot read property 'name' of undefined(…)' error 
}); 

エラーがなくても、以前のコンポーネントコードがサブジェクトにサブスクライブしていた方法が異なり、コントロールがコンポーネントのサブスクリプションに入ることはありませんでした。

私の最初のコードは、私が今、投稿したものとは異なっており、それは、次のリンクに基づいていた - 私はこれはBehaviorSubjectは、すぐにそれが加入しているとして(常にその最初の値を発しているという事実に依存だと思うdelegation-eventemitter-or-observable-in-angular2

答えて

5

大理石の図はこちらhttp://reactivex.io/RxJava/javadoc/rx/subjects/BehaviorSubject.htmlを参照してください)。

あなたのケースで最初に放出される値はnullです。つまり、BehaviorSubjectのコンストラクタで渡した値です。

問題を克服する方法の1つは、null値でないことを確認して(正規のものがあることがわかったので)、演算子skip()を使用して常に最初に出力された値をスキップすることです。

+4

最初のヌル値を取得しないようにするには、 'BehaviorSubject(null)'ではなく 'ReplaySubject(1)'を使用してください。 – Brandon

関連する問題