无法从外部服务器存储提取的json数据

时间:2017-12-13 15:48:20

标签: json angular http ionic-framework

我正在尝试使用以下代码从外部服务器获取一些json数据:

  ionViewDidLoad(){
    console.log("user-detail page loaded");
  }

  fetchData(){
    let loadingPopup = this.loadingCtrl.create({
      content: 'Please wait...'
    });

    loadingPopup.present();

    let user_data = "";
    this.url = this.navParams.get("url");

    return new Promise(resolve => {
      this.http.post(this.url, null)
        .subscribe(data => {
          resolve( data );
          loadingPopup.dismiss();
        });
    });
  }

  ionViewDidEnter(){
    this.fetchData().then(data => {
      this.user = JSON.parse(data._body);
    });
    console.log(this.user);
  }

console.log(this.user)的输出未定义。我想知道我哪里出错了。

1 个答案:

答案 0 :(得分:1)

这种行为是预期的,因为您必须等待从服务器返回HTTP响应。我相信您知道,PromisesObservables异步,因此在您的示例中,您等待响应时仍会执行其余代码服务器。

仅仅因为它在你的控制器中未定义,生命周期钩子并不一定意味着你无法从你的视图中访问它。但是,为了防止视图中出现错误,您可以在视图中使用ngIf以确保在加载特定元素之前数据存在:

<p *ngIf="user">{{ user.displayName}}</p> 

您还可以使用safe navigation operator?):

<p>{{ user?.displayName}}</p> 

作为旁注,我建议坚持使用promises或observables来处理你的HTTP请求,因为我看到你正在将两者结合起来。您还可以考虑将HTTP请求移动到单独的服务文件中,然后将该服务注入控制器。这种模式有助于在应用程序开始增长时保持代码的可管理性。基于您的代码的Here is an example这种模式:

<强> api.service.ts

import { Http } from '@angular/http';
import { Injectable } from '@angular/core';
import { Observable } from "rxjs/Observable";
import 'rxjs/add/operator/map';

@Injectable()
export class ApiService {

  constructor(private http: Http) {}

  fetchData(url: string): Observable<any> {
    return this.http.get(url)
      .map(data => data.json());
  }
}

<强> your.comonent.ts

  constructor(private api: ApiService, private loadingCtrl: LoadingController) { 
    console.group('LifeCycle'); 
  }

  ionViewDidLoad() {
    // will be undefined
    console.log("ionViewDidLoad", this.launch);
  }

  ionViewDidEnter() {
    this.fetchDataFromService();
    // will be undefined
    console.log('ionViewDidEnter', this.launch);
  }

  fetchDataFromService() {
    let loadingPopup = this.loadingCtrl.create({
      content: 'Please wait...'
    });
    loadingPopup.present();

    //let user_data = "";
    this.url = 'https://api.spacexdata.com/v2/launches/latest';

    this.api.fetchData(this.url).subscribe(data => {
      console.log('Server Response', data);
      this.launch = data;
      loadingPopup.dismiss();
    },
    (e:Error) => console.log(e));
  }

StackBlitz