[英]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 void
该property 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.