2017-07-07 36 views
0

我有一个Web应用程序正在从多个API中检索数据,并且应该将这些数据用于某些图表。问题是,当图表呈现时,来自api的数据还没有出现。我尝试使用.then()方法,但它告诉我property then does not exist on type void。此外,我尝试使用ngIf方法,在this answer之后,但是也没有工作。你知道我该怎么解决这个问题吗?如何使用* ngIf作为异步http.get数据请求 - Angular 2

下面是我的组件和我的组件模板。

app.component.ts

import { Component } from '@angular/core'; 
import { Http, Response } from '@angular/http'; 
import { Observable } from 'rxjs/Rx'; 
import 'rxjs/Rx'; 

import * as moment from 'moment'; 

@Component({ 
    selector: 'app-root', 
    templateUrl: './app.component.html', 
    styleUrls: ['./app.component.css'] 
}) 
export class AppComponent { 
    title = 'Mimesi dashboard graphs'; 

    //COUNTS 
    public countIndexerMetaApi; //array of one number populated from http.get 
    public countIndexerMetaNumber; //number extracted into array and stored as an int 
    public countIndexerMetaArray; //array to store countNumber afterwards 

    public countIndexerServedApi; 
    public countIndexerServedNumber; 
    public countIndexerServedArray; 

    public countRealTimeServedApi; 
    public countRealTimeServedNumber; 
    public countRealTimeServedArray; 

    //DATES 
    public dateIndexerMetaToStore; //date got from moment method that needs to be stored 
    public dateIndexerMetaArray; //array to store dates for graph label 

    public dateIndexerServedToStore; 
    public dateIndexerServedArray; 

    public dateRealTimeServedToStore; 
    public dateRealTimeServedArray; 

    //API LINKS 
    private apiCountIndexerMetaUrl: string = 'http://localhost:3000/api/countIndexerMetaApi'; 
    /*  TODO - API FOR COUNT OF OTHER TWO TABLES  */ 
    private apiCountIndexerServedUrl: string = 'http://localhost:3000/api/countIndexerServedApi'; 
    private apiCountRealTimeServedUrl: string = 'http://localhost:3000/api/countRealTimeServedApi'; 

    //VARIABLE FOR TIMEOUT 
    public isDataAvailable:boolean = false; 

    constructor(private http:Http) { 
    let now = moment.locale("it"); 

    //COUNT 
    this.countIndexerMetaApi = 0; 
    this.countIndexerMetaNumber = 0; 
    this.countIndexerMetaArray = []; 

    this.countIndexerServedApi = 0; 
    this.countIndexerServedNumber = 0; 
    this.countIndexerServedArray = [] 

    this.countRealTimeServedApi = 0; 
    this.countRealTimeServedNumber = 0; 
    this.countRealTimeServedArray = [] 

    //DATES 
    this.dateIndexerMetaToStore = ""; 
    this.dateIndexerMetaArray = []; 

    this.dateIndexerServedToStore = ""; 
    this.dateIndexerServedArray = []; 

    this.dateRealTimeServedToStore = ""; 
    this.dateRealTimeServedArray = []; 
    } 

    ngOnInit() { 
    this.getIndexerMetaCount(); 
    this.getIndexerServedCount(); 
    this.getRealTimeServedCount(); 
    } 

    //COUNT 
    getIndexerMetaCount(){ 
    this.http.get(this.apiCountIndexerMetaUrl) 
     .map((res: Response) => res.json()) 
     .subscribe(
      data => { 
       console.log(this.countIndexerMetaApi = data.map(countIndexerMetaApiObj => countIndexerMetaApiObj.countIndexerMetaApi)) 
      }, 
     ); 
    //this.countIndexerMetaNumber = this.countIndexerMetaApi[0]; //<-- timing problem since this.count is not yet got from http.get() so it seems undefined 
    //this.countIndexerMetaArray.push(this.countIndexerMetaNumber); // problem follows through 
    } 
    printCountIndexerMetaArray(){ 
    this.countIndexerMetaApi.forEach(element => { 
     console.log(element); 
    }); 
    } 

    getIndexerServedCount(){ 
    this.http.get(this.apiCountIndexerServedUrl) 
     .map((res: Response) => res.json()) 
     .subscribe(
      data => { 
       console.log(this.countIndexerServedApi = data.map(countObj => countObj.countIndexerServedApi)) 
      }, 
     ); 
    //this.countIndexerServedNumber = this.countIndexerServedApi[0]; //<-- timing problem since this.count is not yet got from http.get() so it seems undefined 
    //this.countIndexerServedArray.push(this.countIndexerServedNumber); // problem follows through 
    } 
    printCountIndexerServedArray(){ 
    this.countIndexerServedApi.forEach(element => { 
     console.log(element); 
    }); 
    } 

    getRealTimeServedCount(){ 
    this.http.get(this.apiCountRealTimeServedUrl) 
     .map((res: Response) => res.json()) 
     .subscribe(
      data => { 
       console.log(this.countRealTimeServedApi = data.map(countObj => countObj.countRealTimeServedApi)) 
      }, 
     ); 
    //this.countRealTimeServedNumber = this.countRealTimeServedApi[0]; //<-- timing problem since this.count is not yet got from http.get() so it seems undefined 
    //this.countRealTimeServedArray.push(this.countRealTimeServedNumber); // problem follows through 
    } 
    printRealTimeServedArray(){ 
    this.countRealTimeServedApi.forEach(element => { 
     console.log(element); 
    }); 
    } 

    //DATES 
    dateIndexerMeta() { 
    this.dateIndexerMetaToStore = moment().add(-122, 'days'); 
    this.dateIndexerMetaArray.push(this.dateIndexerMetaToStore); 
    } 

    dateIndexerServed() { 
    this.dateIndexerServedToStore = moment().add(-122, 'days'); 
    this.dateIndexerServedArray.push(this.dateIndexerServedToStore); 
    } 

    dateRealTimeServed() { 
    this.dateRealTimeServedToStore = moment().add(-122, 'days'); 
    this.dateRealTimeServedArray.push(this.dateRealTimeServedToStore); 
    } 

    //TIMEOUT TRIAL 
    timeoutTrial(){ 
    console.log(this.isDataAvailable); 
    setTimeout(function() {this.isDataAvailable = true; 
     console.log(this.isDataAvailable); 
    }, 5000); //<-- timeout works but other functions don't refresh even if isDataAvailable changed 
    } 

    /*  CHARTS  */ 

    //DATA 
    public lineChartData:Array<any> = [ 
    {data: this.countIndexerMetaArray, label: 'Indexer meta served links'}, 
    ]; 

    public lineChartData1:Array<any> = [ 
    {data: this.countIndexerServedArray, label: 'Indexer served links'}, 
    ]; 

    public lineChartData2:Array<any> = [ 
    {data: this.countRealTimeServedArray, label: 'Real-Time served links'}, 
    ]; 

    //LABELS 
    public lineChartLabels:Array<any> = this.dateIndexerMetaArray; 

    public lineChartLabels1:Array<any> = this.dateIndexerServedArray; 

    public lineChartLabels2:Array<any> = this.dateRealTimeServedArray; 

    //OPTIONS 
    public lineChartOptions:any = { 
    responsive: true, 

    scales: { 
     xAxes: [{ 
     type: 'time', 
     time: { 
      displayFormats: { 
      'millisecond': 'DD MMM', 
      'second': 'DD MMM', 
      'minute': 'DD MMM', 
      'hour': 'DD MMM', 
      'day': 'DD MMM', 
      'week': 'DD MMM', 
      'month': 'DD MMM', 
      'quarter': 'DD MMM', 
      'year': 'DD MMM', 
      } 
     } 
     }], 
    }, 

    }; 

    public lineChartLegend:boolean = true; 
    public lineChartType:string = 'line'; 

    //COLORS 
    public lineChartColors:Array<any> = [ 
    { // grey 
     backgroundColor: 'rgba(255,55,55,0.2)', 
     borderColor: 'rgba(255,55,55,1)', 
     pointBackgroundColor: 'rgba(255,55,55,1)', 
     pointBorderColor: '#fff', 
     pointHoverBackgroundColor: '#fff', 
     pointHoverBorderColor: 'rgba(255,55,55,0.8)' 
    }, 
    ]; 

    //EVENTS 
    public chartClicked(e:any):void { 
    console.log(e); 
    } 

    public chartHovered(e:any):void { 
    console.log(e); 
    } 
} 

app.component.html

<div class="container"> 


<div class="front-end-app"> 
    <ul> 
     <h3>Count Indexer Meta:</h3> 
     <li *ngFor="let countIndexerMetaNumber of countIndexerMetaApi"> 
     {{countIndexerMetaNumber}} 
     </li> 
     <h3>Count Indexer Served:</h3> 
     <li *ngFor="let countIndexerServedNumber of countIndexerServedApi"> 
     {{countIndexerServedNumber}} 
     </li> 
     <h3>Count Real Time Served:</h3> 
     <li *ngFor="let countRealTimeServedNumber of countRealTimeServedApi"> 
     {{countRealTimeServedNumber}} 
     </li> 
    </ul> 
    <hr> 

    <div class="head"> 
     <h1>{{title}}</h1> 
    </div> 
    <hr> 
    <div class="row"> 
     <div class="col-md-6"> 
     <div class="card"> 
      <div class="card-block"> 
      <canvas baseChart width="600" height="400" 
        [datasets]="lineChartData" 
        [labels]="lineChartLabels" 
        [options]="lineChartOptions" 
        [colors]="lineChartColors" 
        [legend]="lineChartLegend" 
        [chartType]="lineChartType" 
        (chartHover)="chartHovered($event)" 
        (chartClick)="chartClicked($event)"></canvas> 
      </div> 
     </div> 
     </div> 
     <div class="col-md-6"> 
     <div class="card"> 
      <div class="card-block"> 
      <canvas baseChart width="600" height="400" 
        [datasets]="lineChartData1" 
        [labels]="lineChartLabels1" 
        [options]="lineChartOptions" 
        [colors]="lineChartColors" 
        [legend]="lineChartLegend" 
        [chartType]="lineChartType" 
        (chartHover)="chartHovered($event)" 
        (chartClick)="chartClicked($event)"></canvas> 
      </div> 
     </div> 
     </div> 
     <div class="col-md-6 offset-md-3"> 
     <div class="card"> 
      <div class="card-block"> 
      <canvas baseChart width="600" height="400" 
        [datasets]="lineChartData2" 
        [labels]="lineChartLabels2" 
        [options]="lineChartOptions" 
        [colors]="lineChartColors" 
        [legend]="lineChartLegend" 
        [chartType]="lineChartType" 
        (chartHover)="chartHovered($event)" 
        (chartClick)="chartClicked($event)"></canvas> 
      </div> 
     </div> 
     </div> 
    </div> 
    </div> 
    <button type="button" class="btn btn-primary" (click)="printCountIndexerMetaArray()"> Click to print count indexer meta array</button> 
    <button type="button" class="btn btn-primary" (click)="printCountIndexerServedArray()"> Click to print count indexer served array</button> 
    <button type="button" class="btn btn-primary" (click)="printRealTimeServedArray()"> Click to print count real time served array</button> 
</div> 

如有任何问题或进一步的解释只是评论,我会回答,立竿见影。谢谢!

+1

代码太多了。你是否尝试过'* ngIf =“items | async作为mydata”'并在'* ngFor =“mydata项中?哪里'项目'在承诺应该解决一个迭代。 – wostex

+0

对不起,不工作的部分是'lineChartData'变量,最上面的三个循环工作正常 – GPecchio

+1

无论如何,请尝试如他所说:'* ngIf =“items | async”'and'* ngIf =“items |异步为mydata“' – trichetriche

回答

1

只需使用一个布尔值显示加载。

public isloading = true; 

在你的http调用中,一旦你得到了所有你想要的数据,就将它设置为false。

this.http.get(this.apiCountRealTimeServedUrl) 
     .map((res: Response) => res.json()) 
     .subscribe(
      data => { 
       this.countRealTimeServedApi = 
        data.map(countObj => countObj.countRealTimeServedApi); 
       this.isloading= false; 
      }, 
     ); 

在你的HTTP具有ngIf为isloading部分

<div *ngIf="isloading" > loading .... </div> 
<div *ngIf="!isloading" > 
    <!-- show the chart contents --> 
</div> 

如果您有多个HTTP调用,那么使用&&

<div *ngIf="isIndexMetaCountloading 
      || isIndexerServedCountLoading 
      || isRealTimeServedCountLoading" > 
    loading ... 
</div> 

<div *ngIf="!isIndexMetaCountloading 
      && !isIndexerServedCountLoading 
      && isRealTimeServedCountLoading" > 
    <!-- show the chart contents --> 
</div> 
0

我没有得到究竟是你的问题,请你再澄清一点。 但是,如果你的问题是这些线路

this.countIndexerServedNumber = this.countIndexerServedApi[0]; 
    //<-- timing problem since this.count is not yet 
    // got from http.get() so it seems undefined 
this.countIndexerServedArray.push(this.countIndexerServedNumber); 
    // problem follows through 

那么它不工作,因为get方法以异步方式工作,因此this.countIndexerServedApi是尚未初始化。所以,为了克服这个问题,你应该把这些语句移到订阅块中,然后这些语句只有在this.countIndexerServedApi被初始化后才会被执行。