У меня есть локальный файл JSON с некоторыми данными. Я хочу извлечь из него только CityCodes и сохранить в массиве. Затем я хочу отправить CityCodes в запрос API OpenWeatherMap. Наконец, вы хотите отобразить все записи о погоде в файле HTML.
CityData.json :
{
"List": [
{
"CityCode": "1248991",
"CityName": "Colombo",
"Temp": "33.0",
"Status": "Clouds"
},
{
"CityCode": "1850147",
"CityName": "Tokyo",
"Temp": "8.6",
"Status": "Clear"
},
{
"CityCode": "2644210",
"CityName": "Liverpool",
"Temp": "16.5",
"Status": "Rain"
}
]
Погода.Service.ts :
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { map } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class WeatherService {
apiKey = '9402da6bd74c395f71604c624cc2b231';
url;
constructor(private http:HttpClient) {
this.url='http://api.openweathermap.org/data/2.5/group?id='; //API GET URL
}
getWeather(cityCode){
return this.http.get(this.url+cityCode+'&units=metric&appid='+this.apiKey);
}
}
home.component.ts :
здесь я передаю код города вручную. Вместо этого мне нужно отправить сюда коды городов в формате JSON.
import { Component, OnInit } from '@angular/core';
import { WeatherService } from "../shared/weather.service";
// import { weather} from "../shared/weather.model";
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
location = {
code: '1248991' //Passing Area Code Manually
};
public weather: any;
constructor(private weatherService:WeatherService) {
}
ngOnInit() {
this.weatherService.getWeather(this.location.code).subscribe((Response:any)=>{
console.info(Response);
this.weather = Response.list;
})
}
}
home.component.html :
<table class = "table table-hover">
<thead>
<th>City</th>
<th>City Code</th>
<th>Temperature</th>
<th>Description</th>
</thead>
<tbody>
<tr *ngFor = "let weather of weather">
<td>{{weather.name}}</td>
<td>{{weather.id}}</td>
<td>{{weather.main.temp}}</td>
<td>{{weather.weather[0].description}}</td>
</tr>
</tbody>
</table>

Сначала прочитайте JSON, используя HTTP get, и используйте forJoin для чтения параллельных (например, Promise.all) данных о погоде из API.
// add in service
get(url){
return this.http.get(url);
}
//component
ngOnInit() {
this.weatherService.get('json file url').subscribe((cities:any)=>{
const {List} = cities;
const obsArr = List.map(location => this.weatherService.getWeather(location.CityCode))
forkJoin(obsArr).subscribe( => { // import forkJoin
console.info(val)
this.weatherlist = val; // modify according to response
});
})
}
//html
<tr *ngFor = "let weather of weatherlist">
<td>{{weather.name}}</td>
<td>{{weather.id}}</td>
<td>{{weather.main.temp}}</td>
<td>{{weather.description}}</td>
</tr>
Обновите службу погоды, чтобы использовать локальный путь к файлу JSON и прочитать содержимое,
public getJsonData(filePath: string){
return this.http.get(filePath);
}
В вашем компоненте сделайте следующее:
export class HomeComponent implements OnInit {
public data: any;
public weather: any;
constructor(private weatherService: WeatherService) {}
ngOnInit() {
this.weatherServiceget.getJsonData(./data.json).subscribe(data => {
this.data = data;
this.getWeatherList();
});
}
getWeatherList(){
if (this.data) {
const dataList = JSON.parse(this.data).List;
for (let temp of dataList) {
this.weatherService.getWeather(temp.CityCode).subscribe((Response: any) => {
console.info(Response);
if (Response && Response.list) {
this.weather.push(Response.list[0]);
}
})
}
}
}
}
вот рабочий пример, он не может читать данные файла в stackblitz, поэтому он жестко запрограммирован. Пример
Не работает..! Должен ли я вызывать метод getWeatherList() внутри ngOnInit()??
ах извините, мой плохой. ДА! вызовите getWeatherList после того, как вы получили данные из файла json. Я тоже обновил код
Я не мог вызвать файл JSON. Мне нужно его импортировать?? это в папке активов.
Получение этой ошибки «Неожиданный токен o в JSON в позиции 1»
тогда ваш json неправильно отформатирован, скопируйте свой json и проверьте его здесь jsoneditoronline.org
Я решил это, вставив ответ JSON в массив.
Home.component.ts
public data: any;
public weather: any;
constructor(private weatherService:WeatherService) {
}
ngOnInit() {
this.weatherService.getJsonData('./assets/City.json').subscribe(data => {
this.data = data; //Reading JSON Data
this.getWeatherList(); //Calling GetWeatherList Function
});
}
getWeatherList(){
if (this.data) {
// console.info(this.data);
const dataList = this.data.List;
let tempArr : any = [];
for (let temp of dataList) {
this.weatherService.getWeather(temp.CityCode).subscribe((Response: any) => {
tempArr.push(Response.list[0]); //Pushing Response to Array
})
}
console.info(tempArr)
this.weather = tempArr; //Assigning Array to Weather Constant
}
}
хорошо './' начните с того места, где находится ваш компонент, если вам нужно вернуться, то '../shared' как вы должны выяснить свой путь