Angular 2/TypeScript: Cum să accesezi o proprietate observabilă în componentă


Am un observable care se populează astfel:

this._mySubscription = this._myService.getSomething(id)
                                .subscribe(
                                    response => this._myData = response, 
                                    error => this.displayError(<any>error),
                                    () => this.stopLoading()
                                );

Pot accesa proprietăți pentru acesta în markup-ul meu HTML folosind operatorul Elvis astfel:

{{_myData?.PropertyNameHere}}

Dar cum accesez aceeași proprietate în componentă folosind TypeScript?

Acest lucru produce o linie roșie ondulată sub proprietate:

this._myData.PropertyNameHere

Și spune:

Proprietatea nu există pe Observable

Actualizare: Exemplu de apel de serviciu

getSomething(id: string): Observable<any> {

let params = 'id=' + id;

return this._http
            .post(apiUrl + 'SomeController/SomeAction', params, {withCredentials: true, headers: this.headers})
            .timeoutWith(maxTimeHttpCalls, Observable.defer(() => Observable.throw(this._feedbackService.timeout())))
            .map((response: Response) => response.json().data.Items);

}

Răspuns #1

_myData din clasă nu ar trebui să fie de tip Observable. Ar trebui să fie tipul obiectului pe care îl returnezi din operatorul map în serviciul tău.

.map((response: Response) => response.json().data.Items)

Indiferent de tipul lui data.Items, acesta ar trebui să fie tipul lui _myData. Dacă nu știi care este tipul, atunci fă-l pur și simplu any. Astfel vei putea face orice cu el fără avertismente de la compilator. Dar dacă știi structura datelor, cel mai bine este să creezi o clasă model pentru ele astfel încât să ai tipizare strictă.

interface SomeModel {
  somProperty: string;
}

getSomething(id: string): Observable<SomeModel> {

  return this._http
             ...
             .map((response: Response) => <SomeModel>)response.json().data.Items);
}

Componenta ta

class MyComponent {
  private _myData: SomeModel;

  this._mySubscription = this._myService.getSomething(id)
    .subscribe((response: SomeModel) => this._myData = response, 
               error => this.displayError(<any>error),
               () => this.stopLoading());
}