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

无法存储从外部服务器获取的json数据,json,angular,http,ionic-framework,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

我正在尝试使用以下代码从外部服务器获取一些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)
的输出未定义。我想知道哪里出了问题。

这种行为是意料之中的,因为您必须等待服务器返回HTTP响应。我相信您知道,
承诺
可观察
是异步的,因此在您的示例中,在等待服务器响应时,您的其余代码仍将执行

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

<p *ngIf="user">{{ user.displayName}}</p> 
作为旁注,我建议对HTTP请求坚持承诺或可观察性,因为我看到您正在将两者结合起来。您还可以考虑将HTTP请求移到单独的服务文件中,然后将该服务注入到控制器中。此模式有助于在应用程序开始增长时保持代码的可管理性。基于您的代码创建这样的模式:

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());
  }
}
  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));
  }

控制台.log
调用移动到
中,然后
回调。如前所述,日志调用在调用
fetchData
和回调之间执行。@headrush可以工作,但我无法使用
user
变量访问HTML文件中的其他json字段。我收到一个运行时错误-
\u co.user未定义
访问HTML文件中的其他json字段是什么意思?
user.timeline
@ExplosionPills
  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));
  }