简体   繁体   English

如何将* ngIf用于异步http.get数据请求-Angular 2

[英]How to use *ngIf for async http.get data request - Angular 2

I have a web application that is retrieving data from multiple api and is supposed to use the data into some charts. 我有一个Web应用程序,该应用程序正在从多个api检索数据,并且应该将数据使用到一些图表中。 The problem is that when the charts get rendered the data from the api are not in yet. 问题在于,当图表被渲染时,来自api的数据还没有。 I tried using .then() method but it tells me that property then does not exist on type void . 我尝试使用.then()方法,但它告诉我, property then does not exist on type voidproperty then does not exist on type void Furthermore I tried using the ngIf method, following this answer , but is not working either. 此外,在此答案之后 ,我尝试使用ngIf方法,但也不起作用。 Do you know how could I solve this please? 你知道我该怎么解决吗?

Below are my component and my component template. 以下是我的组件和组件模板。

app.component.ts 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 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>

For any question or further explanation just comment and I'll answer straight away. 对于任何问题或进一步的解释,请发表评论,我会立即回答。 Thanks! 谢谢!

Just use a boolean to show loading. 只需使用布尔值显示加载即可。

public isloading = true; 

Inside your http call , set this to false once you got all the data you want. 在您的http调用中,一旦获得所需的所有数据,请将其设置为false。

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

In your HTTP have ngIf for the isloading part 在您的HTTP中有ngIf作为isloading部分

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

If you are having multiple HTTP calls then use && 如果您有多个HTTP调用,请使用&&

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

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

U forget implements OnInit [ https://angular.io/guide/lifecycle-hooks][1] 你忘了实现OnInit [ https://angular.io/guide/lifecycle-hooks][1]

export class AppComponent implements OnInit{

Try use Resolver for this component [ https://angular.io/api/router/Resolve][2] 尝试对此组件使用Resolver [ https://angular.io/api/router/Resolve][2]

I am not getting what exactly is your problem, could you please clarify a little more. 我没有弄清楚您的问题是什么,请您再澄清一下。 But if your problem is with these lines 但是如果您的问题在于这些行

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

then it's not working because get method works asynchronously, and therefore this.countIndexerServedApi is yet not initialized. 则它不起作用,因为get方法异步工作,因此this.countIndexerServedApi尚未初始化。 So, to overcome this problem you should move these statements inside the subscribe block and then these statements will be executed only after this.countIndexerServedApi gets initialized. 因此,要解决此问题,您应该将这些语句移到this.countIndexerServedApi块内,然后仅在this.countIndexerServedApi初始化后才执行这些语句。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM