简体   繁体   English

具有字段到数组的Angular Convert API JSON响应对象

[英]Angular Convert API JSON Response Object with Fields to Array

Learning Angular and having been through the heroes tutorial I wanted to try a real world http request so I am hitting the MetOffice DataPoint API. 学习Angular并通过英雄教程我想尝试一个真实世界的http请求,所以我正在使用MetOffice DataPoint API。 A JSON object is being returned that won't currently convert to an array for me to loop through. 正在返回一个JSON对象,该对象当前不会转换为数组供我循环。 I am getting the following error: 我收到以下错误:

Cannot read property 'data' of undefined 无法读取未定义的属性“数据”

Having researched for a while now and tried a number of different suggestions from very similar questions, the closest being this one , below are the various things I have tried with comments on what failed at each attempt. 经过一段时间的研究,并从非常相似的问题尝试了一些不同的建议,最接近这一个 ,下面是我尝试过的各种事情,评论每次尝试失败的事情。 I have confirmed in JSONLint that the JSON is valid. 我已在JSONLint中确认JSON有效。

Model 模型

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

Service 服务

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

  @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);
  }
};

View 视图

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

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

As always, all help greatly appreciated. 一如既往,所有的帮助非常感谢。

EDIT : A snippet of the JSON, it has 4,000 location objects or so. 编辑 :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"
        }]
    }
}

Update Developer Tools showing response 更新开发者工具显示响应

在此输入图像描述

There is no res.json().Location but res.json().Locations (note the "s") and furthermore, there is no object data that you are trying to extract from the response, but Location . 没有res.json().Locationres.json().Locations (注意“s”)此外,您没有尝试从响应中提取的对象data ,而是Location So if you want to extract the array, your extractData should look like this: 因此,如果要提取数组, extractData应如下所示:

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

Its because your extractData callback function expects a argument which is not passed 因为你的extractData回调函数需要一个未传递的参数

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

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

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