2017-09-26 3 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 값은 없습니다.

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

그리고 데이터와 함께 뭔가를 할 :

답변

0

결과가 비동기 적으로 나오기 전에 약속을 해결하고 약속을 한 번만 해결하십시오.

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.deval [as updateRenderer] (ShiftComponent.html : 18) (Object.debugUpdateRenderer [as updateRenderer])에서 정의되지 않은 의 속성 'active'를 읽을 수 없습니다. 서비스에서 this.httpClient.get을 사용하고 있습니다 ('http : // localhost : 8080/shift/isopen'); 지금은이 코드 만 사용하십시오. 오류를 잡으려고 시도조차하지 않습니다. 어떤 제안? 감사. – Saurin

+0

* ngIf = "shiftLive $ async를 shiftLive로 포함시킨 후, div 섹션에서로드가 제대로 작동하기 시작했으나 서버에 대해 여러 번 http 호출을하는 것이 옳습니다. – Saurin

+0

내가 당신을 보여줬을 때 한 번만 구독해야합니다. 관찰 가능한 스트림을 두 개의 호출로 분할 할 필요가 없습니다. 필요한 모든 정보가 동일한 통화에 있습니다. – bryan60

0

나는 당신이 당신의 방법이 방법을 리팩토링해야 shift.service.ts

return Promise.resolve(this.shift); 

에서 checkShiftStatus 방법에 정의되지 않은 값을 반환 추측 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

비동기 파이프가 더 깨끗하고 안전합니다. Observables에 가입하는 선호 된 방법 – bryan60

관련 문제