【问题标题】:Angular Convert API JSON Response Object with Fields to ArrayAngular将带有字段的API JSON响应对象转换为数组
【发布时间】:2017-09-09 10:45:28
【问题描述】:

学习 Angular 并完成了英雄教程,我想尝试一个真实世界的 http 请求,所以我正在使用 MetOffice DataPoint API。正在返回一个 JSON 对象,该对象当前不会转换为数组供我循环使用。我收到以下错误:

无法读取未定义的属性“数据”

现在已经研究了一段时间,并从非常相似的问题中尝试了许多不同的建议,最接近的是this one,下面是我用 cmets 尝试过的各种尝试,每次尝试都失败了。我已经在 J​​SONLint 中确认 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 的一个 sn-p,它有 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"
        }]
    }
}

更新显示响应的开发者工具

【问题讨论】:

  • 您收到的 JSON does 看起来如何? (在网络标签中)
  • 看来您什么都没收到...

标签: arrays json angular asp.net-web-api


【解决方案1】:

没有res.json().Location,而是res.json().Locations(注意“s”),此外,没有您试图从响应中提取的对象data,而是Location。所以如果你想提取数组,你的extractData 应该是这样的:

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

【讨论】:

  • 就是这样。非常感谢您的帮助,我没有想到像那样“踏入”对象并完全误解了 .data
  • 没问题,很高兴能帮上忙! :)
【解决方案2】:

这是因为您的 extractData 回调函数需要一个未传递的参数

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

【讨论】:

  • 在调用中仅传递this.extractData 不是调用函数,因此没有可期望的参数。您在回答中所做的是将 调用 this.extractData(data) 的结果传递给 map(),这是双重错误:数据未定义且 this.extractData 不返回函数。
猜你喜欢
  • 2022-11-19
  • 1970-01-01
  • 2021-05-23
  • 1970-01-01
  • 2011-08-19
  • 1970-01-01
  • 2023-02-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多