2017-07-26 67 views
1

我確定問題是關於異步,但找不到解決方案。我創建了一個獲取JSON數據數組的服務。在我的組件中,我想在頁面加載時顯示這些數據。 當頁面加載時,我沒有收到任何數據,但我創建了一個按鈕,並將onclick事件放在同一個函數中。我在點擊事件上獲取數據。我究竟做錯了什麼?無法在Angular 2的init上獲取Ajax數據

我的組件

import { Component } from '@angular/core'; 
import {PostService} from './post.service'; 

@Component({ 
    selector: 'app-root', 
    template: ` 

    {{test}} 
    <ul> 
    <li *ngFor="let item of jsonArray"> 
    {{item.title}} a 
    </li> 

    </ul> 
    <button on-click="onClick()">button</button> 
    ` 


}) 
export class AppComponent { 
    test; 
    jsonArray : any[]; 
    constructor(private _postService : PostService){ 


    } 

    onClick(){ 
    this.jsonArray = this._postService.getPosts(); 
    this.test = "clicked"; 
    } 

    ngOnInit(){ 
    this.jsonArray = this._postService.getPosts(); 
    this.test = "init"; 

    } 

} 

和我的服務類

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


@Injectable() 
export class PostService { 

    private _url = "https://jsonplaceholder.typicode.com/posts"; 

    jsonArray: any[]; 
    getPosts():any[]{ 
     //return this._http.get(this._url).map(res =>res.json()); 
     this._http.get(this._url).subscribe(response => { 
      this.jsonArray = response.json(); 
      console.log(response.json()); 
      console.log("jsonArray",this.jsonArray); 
     }); 

     return this.jsonArray; 
    } 

    createPost(post){ 
     return this._http.post(this._url,JSON.stringify(post)).map(res =>res.json()); 
    } 
    constructor(private _http:Http){ 

    } 




} 
+0

https://stackoverflow.com/documentation/angular2/3577/angular-rxjs-subjects-and-observables閱讀提供的鏈接-with-api-requests/12348/basic-request#t = 20170726145040649751 – JGFMK

+0

您是否收到任何錯誤。我是使用您的代碼的凝結結果。控制檯中是否有錯誤? –

+0

沒有錯誤,我試圖看到頁面上的數據不在控制檯上。您是否看到網頁上的數據? @RajBahadurSingh – rematnarab

回答

2

您的服務兩個問題:

  1. return是回調外,所以最初的空數組將退回
  2. 即使它不是外面,你不能subscribe返回數據。

我建議你閱讀異步起來:How do I return the response from an asynchronous call?

而且這個How do I return the response from an Observable/http/async call in angular2?解釋了更有棱角的場景此行爲。

另請參閱official tuto of http

這就是說,很快就會說 - 你需要map服務和subscribe組件。

至於你的問題:

加載頁面時,我沒有得到任何數據,但我創建了一個按鈕,並把同樣的功能,它的onclick事件。我在點擊事件上獲取數據。

因此,讓我們在你的服務方法潛水,看看到底是怎麼回事:

getPosts():any[]{ 
    this._http.get(this._url).subscribe(response => { 
     // hey, I'm doing this request now, but I don't know how long it will take 
     this.jsonArray = response.json(); 
     console.log(response.json()); 
     console.log("jsonArray",this.jsonArray); 
    }); 
    /* okay, so I fired the above request, I won't wait until it is complete, 
     I'll just execute the below while I am waiting!*/ 
    return this.jsonArray; 
} 

所以,當你火上OnInit請求它執行HTTP請求,雖然它正在執行它在http請求完成執行之前返回this.jsonArray

所以現在當你點擊按鈕時,它會拒絕http請求,並在它完成之前再次返回你this.jsonArray。但是,嘿,現在我們實際上已經從之前的請求中獲得了值,所以這就是爲什麼您可以獲得數據的原因!

正如前面提到的,你不能返回從認購數據,無論如何,即使是內部的回調,像這樣:

getPosts():any[]{ 
    return this._http.get(this._url).subscribe(response => { 
     .... 
     return this.jsonArray; // WON'T WORK! 
    }); 
} 

所以,你可以做什麼,是map返回數據,這樣做的:

服務:

getPosts():any[]{ 
    this._http.get(this._url) 
     .map(res => res.json()) 
    }); 
} 

組件:

​​

我真的推薦仔細與思想:)

+0

非常感謝,這很明確 – rematnarab

+0

非常歡迎,很高興我能爲你澄清一些事情! :) – Alex