2017-09-26 15 views
0

非同期パイプを使用しようとしていますが、データが表示されません。私はサーバーから来ているデータをログに記録しており、コンソールに正常に表示されます。しかし何らかの理由で私は非同期を動作させることができません。角度4非同期パイプが機能していません

shift.service.ts

import { Injectable } from '@angular/core'; 
import { Shift } from '../shift/shift'; 
import { HttpClient } from '@angular/common/http'; 

@Injectable() 
export class ShiftService { 

    constructor(private shift:Shift, private httpClient:HttpClient 
      ) { this.checkShiftStatus();} 

    checkShiftStatus():Promise<Shift>{ 
    this.httpClient.get<Shift>('http://localhost:8080/shift/isopen') 
     .subscribe((data) => { 
     this.shift = data; 
     console.log(this.shift); 
     }, 
     error => { 
     console.error('Something went wrong while trying to check the shift!'); 
     }); 
    return Promise.resolve(this.shift); 
    } 
} 

shift.component.ts

import { Component, OnInit } from '@angular/core'; 
import { Shift } from './shift'; 
import { ShiftService } from '../services/shift.service'; 

@Component({ 
    selector: 'app-shift', 
    templateUrl: './shift.component.html', 
    styleUrls: ['./shift.component.css'] 
}) 
export class ShiftComponent implements OnInit { 
    isShiftOpen:Promise<boolean>; 

    shiftLive:Promise<Shift>; 

    constructor(private shiftService: ShiftService, public shift:Shift) { } 

    ngOnInit() { 
    this.isShiftOpen = this.getShift().then(shift => this.shift.active = shift.active); 
    this.shiftLive = this.shiftService.checkShiftStatus(); 
    } 

    getShift(){ 
    return this.shiftService.checkShiftStatus().then(shift => this.shift = shift); 
    } 
} 

ボタンがさえていても表示されません

<md-grid-list *ngIf="isShiftOpen | async" cols="2" rowHeight="100px"> 
    <md-grid-tile> 
     <button md-raised-button [disabled]='isShiftOpen' color="primary">Open Shift</button> 
     <button md-raised-button [disabled]='!isShiftOpen' color="warn">Close Shift</button> 
    </md-grid-tile> 
</md-grid-list> 

<md-card class="card"> 
    <md-card-title> 
    Shift Stats: 
    </md-card-title> 
    <md-card-content> 

    </md-card-content> 
</md-card> 
<!-- <div *ngIf="(shiftLive | async)?.notnull; else loading"> --> 
<div *ngIf="shiftLive | async"> 
    <p> Shift status: {{ shiftLive.active }} </p> 

    <p> Tickets Sold: {{ shiftLive.totalNumberOfTicketsSold }} </p> 
</div> 
<ng-template #loading>Loading Data...</ng-template> 

shift.component.htmlサービスはtrueの値を提供しています。 divを表示させますが、shiftLive.active、shiftLive.totalNumberOfTicketsSoldの値はありません。

答えて

0

結果が非同期になる前に約束を解決し、約束は1回だけ解決します。

checkShiftStatus():Promise<Shift>{ 
    let promise = new Promise<Shift>(); 
    this.httpClient.get<Shift>('http://localhost:8080/shift/isopen') 
    .subscribe((data) => { 
     this.shift = data; 
     promise.resolve(this.shift); 
     console.log(this.shift); 
    }, 
    error => { 
     console.error('Something went wrong while trying to check the shift!'); 
    }); 
    return promise; 
} 

そして約束の使用は、コンポーネント内のすべて間違っている:あなたは、未解決の約束を返し、結果がでてくると、あなたの約束を解決するために、このように、待つ必要があります。スコープ外の変数を定義して設定しています。非同期パイプは、このすべてを処理します。

またはいっそのは、全く観測が道優れているので、約束を使用していない

サービス:

// just return the observable stream and don't subscribe, let async handle your subscriptions 
checkShiftStatus():Observable<Shift>{ 
    return this.httpClient.get<Shift>('http://localhost:8080/shift/isopen') 
    .do((data) => { 
     // you really shouldn't do this. statefulness like this is a sign of bad design 
     this.shift = data; 
     console.log(this.shift); 
    }).catch(err => { 
    console.log('make sure to handle this error'); 
    Observable.throw(err); 
    }); 
} 

コンポーネント:

// only set this once so that we don't make the same http call over and over, we have all the data we need here (the $ syntax is standard for denoting an observable) 
this.shiftLive$ = this.shiftService.checkShiftStatus(); 

テンプレート:

//only use async once to avoid multiple subscriptions, and declare it "as" whatever you want, and then you have access to it throughout the template, you can still use your loading template as you want. 
<ng-container *ngIf="shiftLive$ | async as shiftLive; else loading"> 
<md-grid-list *ngIf="shiftLive.active" cols="2" rowHeight="100px"> 
    <md-grid-tile> 
     <button md-raised-button [disabled]='shiftLive.active' color="primary">Open Shift</button> 
     <button md-raised-button [disabled]='!shiftLive.active' color="warn">Close Shift</button> 
    </md-grid-tile> 
</md-grid-list> 

<md-card class="card"> 
    <md-card-title> 
    Shift Stats: 
    </md-card-title> 
    <md-card-content> 

    </md-card-content> 
</md-card> 

<div> 
    <p> Shift status: {{ shiftLive.active }} </p> 

    <p> Tickets Sold: {{ shiftLive.totalNumberOfTicketsSold }} </p> 
</div> 
<ng-template #loading>Loading Data...</ng-template> 
</ng-container> 
+0

あなたの提案された変更を行い、プログラムを実行しようとしました。しかし、エラーを示すエラーで終了しました。TypeError:Object.devalue(as a updateRenderer)(ShiftComponent.html:18) (Object.debugUpdateRenderer as updateRenderer)で未定義の のプロパティ 'active'を読み取ることができません。 サービスでは、私はthis.httpClient.getを使用しています( 'http:// localhost:8080/shift/isopen');今はこのコードだけです。エラーをキャッチしようとしない。助言がありますか?ありがとう。 – Saurin

+0

* ngIf = "shiftLive $ | asyncをshiftLiveとして追加した後、divセクションにロードするとうまくいきました。 – Saurin

+0

私があなたを見せた時に一度だけ購読する必要があります。観測可能なストリームを2つの呼び出しに分割する必要はありません。必要なすべての情報が同じコールにあります。 – bryan60

0

私はあなたがこの方法あなたの方法をリファクタリングする必要がありshift.service.ts

return Promise.resolve(this.shift); 

からあなたcheckShiftStatus方法で未定義の値を返す推測:

checkShiftStatus(): Observable<Shift>{ 
    return this.httpClient.get<Shift>('http://localhost:8080/shift/isopen') 
} 

そして、あなたのデータで何かを行いますshift.component.tsとshift.component.html:

export class ShiftComponent implements OnInit { 

    shift: any; 

    constructor(private shiftService: ShiftService, public shift:Shift) { } 

    ngOnInit() { 
    this.getShift(); 
    } 

    getShift(): void { 
    this.shiftService.checkShiftStatus() 
     .subscribe(shift => this.shift = shift); 
    } 

    isActive(): boolean { 
    return this.shift && this.shift.active; 
    } 

    ticketsSold(): number { 
    return this.shift ? this.shift.totalNumberOfTicketsSold : 0; 
    } 
} 

<md-grid-list *ngIf="isActive()" cols="2" rowHeight="100px"> 
    <md-grid-tile> 
    <button md-raised-button [disabled]='isActive()' color="primary">Open Shift</button> 
    <button md-raised-button [disabled]='!isActive()' color="warn">Close Shift</button> 
    </md-grid-tile> 
</md-grid-list> 

<md-card class="card"> 
    <md-card-title> 
    Shift Stats: 
    </md-card-title> 
    <md-card-content> 
    </md-card-content> 
</md-card> 
<!-- <div *ngIf="shift?.notnull; else loading"> --> 
<div *ngIf="shift"> 
    <p> Shift status: {{ isActive() }} </p> 
    <p> Tickets Sold: {{ ticketsSold() }} </p> 
</div> 
<ng-template #loading>Loading Data...</ng-template> 
+0

非同期パイプはよりクリーンで安全です観察可能なものを購読するための好ましい方法 – bryan60

関連する問題