2017-02-11 10 views
2

jsonファイルの情報でビューの変数を作成することはできませんが、私はとても近いです。 .subscribe() -chainの情報をエコーアウトできますが、変数に設定されません。定義されません。何が間違っていますか?Angular 2のhttp.getからJSONデータを正しく抽出するにはどうすればよいですか?

jsonファイルをコンポーネントビューの変数にロードするだけです。これは、角度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

これは非同期操作なので、結果が未定義の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サービス中およびコンポーネントに、観察を返し、returnステートメントを追加することを忘れないでください:あなたのコンポーネントで

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

を私はあなたの代わりにOnInitであなたのサービスコールを移動することをお勧め。ここでは、コード内のコメントごとに値が即座にサブスクリプションの外部にアクセスできないことに気付くこともできます。あなたが何らかの形で自分のデータを操作したいのであれば、あなたはそうするので、あなたのビューでngIfまたはsafe navigation operatorのいずれかを使用するように調製され、考慮にそれを取るために:)

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

を、これは非同期操作であるAS必要データが取得される前にビューがレンダリングされます。

だから、どちらかのラップngIf中にあなたのコード:

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

または{{gullkorn?.someProperty}}

+0

ありがとうございました!これは最初の試みで働いた、私のためのそのような闘いだった。時間をすごく感謝します。コンポーネントをサブスクライブしてこの関数を呼び出すと、トリックがかかりました! –

+1

あなたは大歓迎です!うん分かりました。非同期操作は最初は非常に混乱しています!私の答えでこれをもう少し詳しく説明しました。gページのナビゲーションに何らかの形でコンポーネント内のデータを操作する必要がある場合は、サブスクリプションでデータが利用できる場所に注意する必要があります。どこにいなくても、将来的には役立つと思っています。 :) – Alex

1

それはコンポーネントで、それまでのサービスから、観察を返し、サブスクライブすると良いでしょう:

サービス:

@Injectable() 
export class GullkornService { 

    constructor(private http:Http) { 
    } 

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

} 

comp onent:

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

} 
+0

ありがとう!これが今私がやる方法です。しかし、私はこれを辞退する必要があるのか​​、それとも自動的に起こるのでしょうか? –

+0

あなたは 'ngOnInit'でサブスクライブし、' ngOnDestroy'でサブスクライブすることができます –

関連する問題