1

I have a local JSON File with some data. I want to extract only the CityCodes from it and store in an Array. Then i want to send the CityCodes to the OpenWeatherMap API Request. Finally want to Display all the Weather Records in the HTML file.

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"
    }
]

Weather.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 :

here i am passing the area code manually. Instead of that i need to send the area codes form JSON here.

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.log(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>

3 Answers 3

2

I Solved it by pushing the JSON Response into an Array.

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.log(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.log(tempArr)
      this.weather = tempArr;   //Assigning Array to Weather Constant
    }
  }
Sign up to request clarification or add additional context in comments.

Comments

1

read JSON first using HTTP get and use forJoin to read parallel(like Promise.all) weather data from 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.log(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>

Comments

1

Update the weather service to take the local JSON file path and read the content,

  public getJsonData(filePath: string){
        return this.http.get(filePath);
  }

In you component do the following,

  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.log(Response);
          if (Response && Response.list) {
            this.weather.push(Response.list[0]);
          }
        })
      }
    }
  }
}

here is a working example, cannot read file data on stackblitz so its hardcoded. Example

6 Comments

well './' start from where your component is, if you have to go back then '../shared' like the you have to figure out your path
Not Working..! Should I call getWeatherList() Method inside ngOnInit() ??
ah sorry, my bad. YES! call getWeatherList after you got data from json file. I updated the code as well
I Couldnt call the JSON File. Do i need to import it ?? its in a assets folder.
Getting This Error "Unexpected token o in JSON at position 1"
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.