#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 api2. Теперь он выдает другую ошибку: «Не удается найти имя ‘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
модулем, и они также экспортируются по-разному.
-
Http
-> является основным модулем , который требует от пользователя вызоваres.json()
. Это было распространено до появления Angular версии 4.0. -
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 поддерживает привязку только к итерабельным элементам, таким как массивы.