2017-04-13 19 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); 
    }