Как извлекать и использовать данные из файла JSON в Angular7

#json #angular

#json #angular

Вопрос:

Я пытаюсь извлечь данные из файла JSON и отобразить эти данные в форме

Ссылка на ФАЙЛ JSON:https://raw.githubusercontent.com/datameet/railways/master/trains.json

Я пытаюсь использовать приведенный ниже код. Но он возвращает следующую ошибку в файле fetchdata.component.ts:

Свойство ‘json’ не существует для типа ‘Object’.

fetchdata.component.ts

 import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-fetchdata',
  templateUrl: './fetchdata.component.html',
  styleUrls: ['./fetchdata.component.css']
})

export class FetchdataComponent implements OnInit {

  private _trainUrl = "https://raw.githubusercontent.com/datameet/railways/master/trains.json
";
  items : any;
  constructor(private http:HttpClient) {
    this.http.get( this._trainUrl)
      .subscribe(res => this.items = res.json());
    console.log(this.items);
  }

  ngOnInit() {
  }

}
  

fetchdata.component.html

 <select>
  <option  *ngFor="let item of items" [value]="item.properties.from_station_name">{{item.properties.from_station_name}}</option>
</select>
  

Пожалуйста, помогите.

Комментарии:

1. Попробуйте console.log(res) ? Вероятно, он уже возвращает само тело ответа. Вам нужно использовать .json() только в том случае, если вы используете собственный fetch api

2. Теперь он выдает другую ошибку: «Не удается найти имя ‘res'».

3. Я понимаю.. Я предполагаю, что ни один из приведенных ниже ответов не решает и вашу проблему тоже?

4. привет, @Tony7931, пожалуйста, проверьте ответ API. вы можете получить объект в ответ, и этот объект перейдет в *ngFor , который недействителен, а также вы можете напрямую назначить res для this.items . Нравится this.items = res

Ответ №1:

Ответ, вероятно, не такой, как вы думаете. Я предлагаю вам console.log() ответ на ваш запрос, чтобы посмотреть, как он выглядит на самом деле:

     items : any;
    constructor(private http:HttpClient) {
      this.http.get( this._trainUrl)
        .subscribe(res => {
          this.items = res.features; 
          console.log("Response", res);
          console.log(res.features)
        });
    }
  

Вы увидите, что на самом деле вы получаете что-то подобное в своей консоли:

 {type: "FeatureCollection", features: Array(5208)}
features: (5208) [{…}, …]
type: "FeatureCollection"
__proto__: Object
  

Таким образом, вы можете присвоить своим элементам features ключ, поскольку это то, что вам действительно нужно:

  constructor(private http:HttpClient) {
      this.http.get( this._trainUrl)
        .subscribe(res => {
          this.items = res["features"]; 
        });
    }
  

Затем должны появиться выбранные вами параметры.

Просто сообщаю вам, что это не идеальный способ сделать это, но он отлично работает для небольшого примера, подобного этому. Я предлагаю вам подумать о создании сервиса для любого запроса в будущем (делать это в конструкторе — не лучший способ) и взглянуть на библиотеку RxJS

Комментарии:

1. Спасибо. Это работает, и спасибо за предложение, я посмотрю на библиотеку RxJS.

Ответ №2:

Существует разница между угловыми Http и HttpClient модулем, и они также экспортируются по-разному.

  1. Http -> является основным модулем , который требует от пользователя вызова res.json() . Это было распространено до появления Angular версии 4.0.

  2. HttpClient -> является новым модулем с версии 4.0. По умолчанию связь передается в формате json, и, следовательно, вам не нужно вызывать res.json() явно.

Короче говоря, переход с res.json() на просто res устранит проблему для вас.

то есть this.items = res; все должно быть в порядке.

Кроме того, в качестве хорошей практики используйте ngOnInit метод жизненного цикла вместо конструктора для выполнения любых Http-вызовов.

Комментарии:

1.Я получаю эту ошибку в консоли Chrome, и она не показывает никаких данных в Select: не удается найти другой поддерживающий объект ‘[object Object]’ типа ‘object’. ngFor поддерживает привязку только к итерабельным элементам, таким как массивы. Я написал это: .subscribe(res => this.items = res); console.log(this.items);

2. Это потому, что trains.json URL, который вы вызываете, возвращает объект json вместо массива. И вы, вероятно, пытаетесь повторить это в своем шаблоне с помощью ngFor . Проверьте правильное свойство и его тип, который вы присваиваете select компоненту.

Ответ №3:

Зачем вы это делаете this.items = res.json() ? Почему бы просто не this.items = res ? res уже должен содержать объект JSON, возвращенный из запроса GET. Если это действительно строка, попробуйте this.items = JSON.parse(res) .

Ответ №4:

Можете ли вы попробовать :

 private _trainUrl = "https://raw.githubusercontent.com/datameet/railways/master/trains.json";
  items : any;
constructor(private http:HttpClient) {}


  ngOnInit() {
    this.http.get( this._trainUrl).subscribe(res => {
      this.items = res;
      console.log(this.items);
    });
  }
  

Комментарии:

1. Это работает, но частично. Данные JSON отображаются в консоли, но не в Select. В консоли выдается эта ошибка: не удается найти другой поддерживающий объект ‘[object Object]’ типа ‘object’. ngFor поддерживает привязку только к итерабельным элементам, таким как массивы.

Ответ №5:

Вам не нужно вызывать .json() функцию, если вы делаете это просто this.http.get . Angular сделает это за вас. Просто делай this.items = res . Это поможет.

UPD: ваш объект JSON сам по себе не является массивом. Вам также необходимо обновить свой шаблон следующим образом:

 <select>
  <option  *ngFor="let item of items.features" [value]="item.properties.from_station_name">{{item.properties.from_station_name}}</option>
</select>
  

Комментарии:

1. Вы предлагаете сделать это: элементы: любые; res: любой; конструктор (частный http:HttpClient ) { this.http.get( this._trainUrl) .subscribe(res => this.items = res); console.log(this.res); }

2. Просто измените this.items = res.json() на this.items = res в предоставленном вами коде. console.log(items) вернет undefined в вашем примере, поскольку http.get является асинхронной операцией.

3. Теперь я получаю эту ошибку в консоли Chrome, и она не показывает никаких данных в Select: не удается найти другой поддерживающий объект ‘[object Object]’ типа ‘object’. ngFor поддерживает привязку только к итерабельным элементам, таким как массивы.