如何正确地从Angular 2中的http.get中提取JSON数据?

时间:2017-02-11 08:14:58

标签: angular angular2-services

我似乎无法使用json文件中的信息为视图创建一个变量但是我非常接近。我可以回复.subscribe() - 链中的信息,但它不会将其设置为变量,它们只是未定义,我做错了什么?

我只想将我的json文件加载到组件视图中的变量中。 Angular 1很容易。

我的服务:

import { Injectable } from '@angular/core';
import { Http, Response, Headers, RequestOptions } from '@angular/http';
import 'rxjs/add/operator/map';
import {Observable} from 'rxjs/Rx';

@Injectable()
export class GullkornService { 
result: any;

constructor(private http:Http) {
}

getGullkorn()  {

let result = this.result;
this.http.get('./gk/gullkorn.json')
.map(res => res.json())
.subscribe(
        val => this.result = val,
        err => console.error(err),
        () =>  console.log(this.result));  // this one echoes out what i want
        console.log(this.result); // but this one doesnt, so i cant return it 
      }
}

着陆组件:

import { Component, OnInit } from '@angular/core';
import {Router, RouterOutlet} from '@angular/router';
import { HttpModule, JsonpModule } from '@angular/http';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule }      from '@angular/core';
import { GullkornService } from '../../gullkorn-service.service';
import { FormsModule }   from '@angular/forms';
import {Observable} from 'rxjs/Observable';

import "gsap";
declare var ease, TimelineMax,TweenMax,Power4,Power1,Power2,Power3,Bounce, Elastic:any;

@Component({
  selector: 'gullkorn-visning',
  providers: [GullkornService],
  templateUrl: './landing.component.html',
  styleUrls: ['./landing.component.css']
})
export class LandingComponent implements OnInit {
  gullkorn: any;
  constructor(GullkornService: GullkornService) { 
        this.gullkorn = GullkornService.getGullkorn();
        console.log(this.gullkorn);
  }

  ngOnInit() {
  }

}

基于当前代码,这是我得到的:

result

我在这里有项目:github

2 个答案:

答案 0 :(得分:2)

这是一个异步操作,因此当您尝试console.log时,结果是未定义的,因为它在订阅中的其他console.log之前运行。

.subscribe(
        val => this.result = val,
        err => console.error(err),
        () =>  console.log(this.result));  // is run sometimes later
        console.log(this.result); // is run first
      }

我会对您的代码进行一些更改...我建议您在组件中处理订阅,这将是处理http请求的最佳方式。所以只需在服务中map并将observable返回给组件,记得添加return语句:

getGullkorn() {
  return this.http.get('./gk/gullkorn.json')
    .map(res => res.json())
}

在您的组件中,我建议您转移OnInit中的服务电话。在这里,您还可以注意到,根据代码中的注释,不能在订阅之外立即访问这些值。因此,如果您想以某种方式操纵数据,则需要考虑到这一点:)

ngOnInit() {
  this.GullkornService.getGullkorn()
    .subscribe(data => {
     // is run sometimes later
     this.gullkorn = data
  });
  // is run first
}

由于这是异步操作,因此请准备好在视图中使用ngIf safe navigation operator ,因为在检索数据之前会呈现视图。< / p>

所以要么将代码包装在ngIf

<div *ngIf="gullkorn"></div>

{{gullkorn?.someProperty}}

答案 1 :(得分:1)

最好从服务中返回observable并在组件中订阅它:

服务:

@Injectable()
export class GullkornService {

  constructor(private http:Http) {
  }

  getGullkorn()  {
    // Return the observable here
    return this.http.get('./gk/gullkorn.json')
    .map(res => res.json());
  }

}

成分:

@Component({
  selector: 'gullkorn-visning',
  providers: [GullkornService],
  templateUrl: './landing.component.html',
  styleUrls: ['./landing.component.css']
})
export class LandingComponent implements OnInit {
  gullkorn: any;
  constructor(GullkornService: GullkornService) { 
      GullkornService.getGullkorn()
        .subscribe(
            val => this.gullkorn = val,
            err => console.error(err)
  }

  ngOnInit() {
  }

}
相关问题