简体   繁体   English

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

[英]How to extract JSON data from http.get in Angular 2 properly?

I can't seem to manage to make a variable for the view with the info from a json file but I'm so close. 我似乎无法使用json文件中的信息为视图创建变量,但我是如此接近。 I can echo out the information in the .subscribe() -chain, but it won't set it to a variable, they just get undefined, what am I doing wrong? 我可以在.subscribe()链中回显信息,但不会将其设置为变量,它们只是未定义,我在做什么错?

I just want to load my json file into a variable in the component view. 我只想将json文件加载到组件视图中的变量中。 It was easy in Angular 1. 在Angular 1中这很容易。

My service: 我的服务:

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 
      }
}

And the landing component: 和着陆组件:

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

}

Based on current code this is what I get: 根据当前代码,这就是我得到的:

结果

I have the project here: github . 我在这里有项目: github

This is an async operation, so when you try to console.log the result it's undefined, as it is being run before the other console.log inside the subscription. 这是一个异步操作,因此当您尝试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
      }

I would make some changes to your code... I would suggest you take care of the subscription in the component instead, this would be the best way to handle http-requests. 我将对您的代码进行一些更改...建议您代替组件中的订阅,这将是处理http请求的最佳方法。 So just map in the service and return the observable to the component, remember to add return statement : 因此,只需在服务中map并将可观察到的内容返回给组件,请记住添加return语句:

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

In your component I would suggest you move your service call in OnInit instead. 在您的组件中,我建议您改为在OnInit移动服务呼叫。 Here you can also notice that the values aren't instantly accessible outside the subscription as per comments in code. 在这里您还可以注意到,根据代码中的注释,不能在订阅之外立即访问这些值。 So if you want to manipulate your data somehow, you need to take that into consideration :) 因此,如果您想以某种方式处理数据,则需要考虑到这一点:)

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

AS this is an async operation, so be prepared to use either ngIf or the safe navigation operator in your view, since view is rendered before data has been retrieved. 由于这是异步操作,因此请准备在视图中使用ngIf安全导航运算符 ,因为视图是在检索数据之前呈现的。

So either wrap your code inside ngIf : 因此,可以将代码包装在ngIf

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

or {{gullkorn?.someProperty}} {{gullkorn?.someProperty}}

It's better to return the observable from the service and subscribe to it in the component: 最好从服务中返回可观察对象并在组件中进行订阅:

service: 服务:

@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: 零件:

@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() {
  }

}

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

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