通过 Angular 5 读取/下载 JSON 文件并将数据存储在本地 JSON 文件中

Posted

技术标签:

【中文标题】通过 Angular 5 读取/下载 JSON 文件并将数据存储在本地 JSON 文件中【英文标题】:Read/download JSON file and store data in a local JSON file via angular 5 【发布时间】:2018-11-03 22:59:11 【问题描述】:

我正在尝试从 openweathermap 中读取 JSON 文件,并在 angular 5 的帮助下将其存储在本地 JSON 文件中。但由于未知原因,我在浏览器检查器中收到以下消息:

core.js:1448 ERROR Error: Error trying to diff 'Rotterdam'. Only arrays and iterables are allowed

不确定这到底是什么意思,尝试用谷歌搜索该问题确实找到了任何解决方案。此外,当我调试时,它看起来可以从 openweathermap 正确读取 JSON,但我感觉当我尝试将其订阅到本地 JSON 时,我做错了。

这是服务的代码:

import  Injectable  from '@angular/core';
import  Http, RequestOptions, Headers, Response  from '@angular/http';
import  Observable  from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/of';

import  City  from '../_models/city.model';
import  Search  from '../_models/search.model';
import  variable  from '@angular/compiler/src/output/output_ast';

const API_URL_SEARCH = 'http://localhost:3000/search';
const API_ARGS: RequestOptions = new RequestOptions();
const headers = new Headers();
headers.append('Content-Type', 'application/json');
API_ARGS.headers = headers;

@Injectable()
export class CityService 
  searchList: Search[];
  private searchURL = 'http://openweathermap.org/data/2.5/weather?q=rotterdam&appid=b6907d289e10d714a6e88b30761fae22';
  constructor(private http: Http)  

  getOpenWeatherMap(): Observable<Search[]> 
    return this.http.get(this.searchURL)
                    .map(this.extractData)
                    .catch(this.handleError);
  

  private extractData(res: Response) 
    const body = res.json();
    return body;
  

  private handleError(error: Response | any) 
    console.error(error.message || error);
    return Observable.throw(error.message || error);
  
 

以及组件的代码:

import  Component, OnInit  from '@angular/core';
import  Observable  from 'rxjs/Observable';
import  CityService  from '../_shared/city.service';
import  Search  from '../_models/search.model';


@Component(
  selector: 'app-city',
  templateUrl: './city.component.html',
  styleUrls: ['./city.component.css']
)
export class CityComponent implements OnInit 

  searches: Observable<Search[]>;
  searchList: Search[];
  errorMessage: String;
  constructor(private cityService: CityService)  

  ngOnInit() 
    this.searches = this.cityService.getSearches();
  

  getOpenWeatherMap() 
    // this.cityService.getOpenWeatherMap()
    //                 .subscribe(result => this.searches = this.cityService.getOpenWeatherMap());
    this.searches = this.cityService.getOpenWeatherMap();
    this.searches.subscribe(
      searchList => this.searchList = searchList,
      error => this.errorMessage = <any>error
    );
  

模型代码:

export class Search 
  constructor(
      public coord: Coord,
      public weather: Weather,
      public base: string,
      public main: Main,
      public visability: string,
      public wind: Wind,
      public clouds: Clouds,
      public dt: string,
      public sys: Sys,
      public id: string,
      public name: string,
      public cod: string
  ) 


export class Coord 
  constructor(
      public lon: string,
      public lat: string
  ) 


export class Weather 
  constructor(
    public id: string,
    public main: string,
    public description: string,
    public icon: string
  ) 


export class Main 
  constructor(
    public temp: string,
    public pressure: string,
    public sea_level: string,
    public humidity: string,
    public temp_min: string,
    public temp_max: string
  ) 


export class Wind 
  constructor(
    public speed: string,
    public deg: string
  ) 


export class Clouds 
  constructor(
    public all: string
  ) 


export class Sys 
  constructor(
    public type: string,
    public message: string,
    public country: string,
    public sunrise: string,
    public sunset: string
  ) 

HTML代码如下:

<div class = "container">
  <h2>Search for city</h2>

    <form>
        <div class = "row" >
          <div class="col-sm-12">
      <label for="cityField">City Name:</label>
      <input class="cityField" #cityField>
      <button class="btn btn-primary" (click)="getOpenWeatherMap()">Search</button>
    </div>
    </div>
    </form>

    <div *ngIf="errorMessage"> errorMessage </div>

    <div class="container">
      <h2>Search</h2>
      <table class="table" style="width:100%">
        <tr>
            <th>City Name</th>
            <th>Country</th>
            <th>weather</th>
            <th>Temp (°C)</th>
            <th></th>
          </tr>
          <tr *ngFor="let Search of searches | async">
              <td>Search.name</td>
              <td>Search.sys.country</td>
              <td>Search.weather[0].description</td>
              <td>Search.main.temp</td>
              <td><button class="btn btn-danger" (click)="deleteCity(Search)">Delete</button></td>
            </tr>
      </table>
  </div>   
</div>

任何帮助将不胜感激。顺便说一句,我刚开始使用角度,所以请记住我不是那么熟练。

【问题讨论】:

【参考方案1】:

所以经过多次调查后,我找出了确切的问题所在。正如错误声明所提到的,它只能处理数组和可迭代对象。所以我们得出的结论是只制作整个 JSON 的数组。

所以在服务中:

private extractData(res: Response) 
   const body = res.json();
   return body;

这必须变成:

private extractData(res: Response) 
   const body = Array.of(res.json());
   return body;

这修复了错误,我可以正确读出 JSON 并将参数复制到本地 JSON 文件。

【讨论】:

以上是关于通过 Angular 5 读取/下载 JSON 文件并将数据存储在本地 JSON 文件中的主要内容,如果未能解决你的问题,请参考以下文章

Angular 5 Service读取本地.json文件

Angular 5 - 实现数据服务以从 MongoDB 读取 JSON

在 Angular2 中使用 Typescript 读取 JSON

angular.json文件中字段含义

Angular读取JSON文件的方法

Angular 5下载带有发布请求的excel文件