2017-04-13 20 views
1

學習Angular並已經通過英雄教程我想嘗試一個真實世界的http請求,所以我點擊MetOffice DataPoint API。正在返回的JSON對象目前不會轉換爲數組供我循環。我收到以下錯誤:Angular轉換帶有字段的API JSON響應對象到數組

Cannot read property 'data' of undefined

已經研究了一段時間了,並試圖從非常類似的問題了一些不同的建議,最接近的是this one,下面是我有什麼沒意見試過了各種各樣的事情在每次嘗試。我已經在JSONLint中確認JSON是有效的。

型號

export class Site { 
    elevation: number; 
    id: number; 
    latitude: number; 
    longitude: number; 
    name: string; 
    region: string; 
    unitaryAuthArea: string; 
} 

服務

@Injectable() 
export class MetOfficeService { 
    private testUrl = 'http://datapoint.metoffice.gov.uk/public/data/val/wxfcs/all/json/sitelist?key=xxx'; 

    constructor(private http: Http) { } 
    getSites(): Observable<Site[]> { 
     return this.http.get(this.testUrl) 
        .map(this.extractData) 
        .catch(this.handleError); 
    } 

    private extractData(res: Response){ 
     let body = res.json().Location; Cannot read property 'data' of undefined 
     //let body = res.json()['Location']; Cannot read property 'data' of undefined 
     //let temp = res.json()['Location']; 
     //let body = JSON.parse(temp); Unexpected token o on line 1 ... this is because of unrequired parsing i have discovered 
     //return body || { }; this is nonsense. 
     return body.data || { }; 
    } 

    private handleError (error: Response | any) { 
    // In a real world app, you might use a remote logging infrastructure 
    let errMsg: string; 
    if (error instanceof Response) { 
     const body = error.json() || ''; 
     const err = body.error || JSON.stringify(body); 
     errMsg = `${error.status} - ${error.statusText || ''} ${err}`; 
    } else { 
     errMsg = error.message ? error.message : error.toString(); 
    } 
    console.error(errMsg); 
    return Observable.throw(errMsg); 
    } 
} 

組件

@Component({ 
    selector: 'app-root', 
    templateUrl: './app.component.html', 
    styleUrls: ['./app.component.css'], 
    providers: [MetOfficeService] 
}) 
export class AppComponent implements OnInit { 
    title = 'test!'; 
    errorMessage: string; 
    sites: Site[]; 

    ngOnInit() { this.getSites(); } 

    constructor(private moService: MetOfficeService) { } 
    getSites(){ 
     this.moService.getSites() 
     .subscribe(
      sites => this.sites = sites, 
      error => this.errorMessage = <any>error); 
    } 
}; 

查看

<h1> 
    {{title}} 
</h1> 

<div id="sites"> 
    <ul> 
    <li *ngFor="let site of sites"> 
     {{site.name}} ||| {{site.unitaryAuthArea}} 
    </li> 
    </ul> 
</div> 

一如既往,所有的幫助非常感謝。

編輯:JSON片段,它有4,000個位置對象左右。

{ 
    "Locations": { 
     "Location": [{ 
      "elevation": "7.0", 
      "id": "3066", 
      "latitude": "57.6494", 
      "longitude": "-3.5606", 
      "name": "Kinloss", 
      "region": "gr", 
      "unitaryAuthArea": "Moray" 
     }, { 
      "elevation": "6.0", 
      "id": "3068", 
      "latitude": "57.712", 
      "longitude": "-3.322", 
      "obsSource": "LNDSYN", 
      "name": "Lossiemouth", 
      "region": "gr", 
      "unitaryAuthArea": "Moray" 
     }, { 
      "elevation": "36.0", 
      "id": "3075", 
      "latitude": "58.454", 
      "longitude": "-3.089", 
      "obsSource": "LNDSYN", 
      "name": "Wick John O Groats Airport", 
      "region": "he", 
      "unitaryAuthArea": "Highland" 
     }] 
    } 
} 

更新開發工具顯示響應

enter image description here

+1

如何*不*的JSON看起來像一個說法你收到了嗎? (在網絡標籤) – Alex

+1

看來你只是沒有收到任何東西...... – n00dl3

回答

2

沒有res.json().Locationres.json().Locations(注意 「S」),此外,也沒有對象data您試圖提取從響應,但Location。所以,如果你想提取數組,你extractData應該是這樣的:

private extractData(res: Response){ 
    let body = res.json().Locations.Location; 
    return body || []; 
} 
+0

就是這樣。非常感謝你的幫助,我沒有想過「踏入」這樣的對象,並完全誤解.data – K7Buoy

+0

沒問題,很高興我可以幫忙! :) – Alex

1

它,因爲你的ExtractData由回調函數預計其不通過

getSites(): Observable<Site[]> { 
     return this.http.get(this.testUrl) 
        .map(this.extractData(data)) 
        .catch(this.handleError); 
    }