0

i createad basic weather app with react, and i want to all json file push the STATE but i can not do that.

import React, {Component} from 'react';
import './App.css';
import CityList from './CityList';
// this is an array that just has id, city_name and country property
import {cityName} from './Resorces';

class App extends Component {
  constructor (){
    super()
    this.state = {
      cities:{},
    }
  }

  render() {
    const {cities} = this.state;
    console.log('cities state', cities);

    return (
      <div className='tc'>
        <h1 className='f1  pa3 ma2'> World Weather</h1><hr/>
        <CityList cities={cities}/>
      </div>
    );
  }
 componentDidMount(){
  const citySource = cityName.map((city) => {
    return fetch(https://api.weatherbit.io/v2.0/current?city=${city.name}&country=${city.country}&key=86e622607fbe4c2cb9f7f71889a4d48d)
      }).then(response => response.json())
       .then( data => {this.setState({cities : data})});
    console.log('citySource', citySource);
  }
}
export default App;

this code above dont access cityName array in Resorces.js and didnt execute map() loop and therefore didnt push json file to cities that a object in STATE

how can i do those?

and It is the cityName array in below

export const cityName = [
  {
    id: 1,
    name: "New York City",
    country: "US",
  },
  {
    id: 2,
    name: "Vienna",
    country: "AT",
  },
  {
    id: 3,
    name: "Istanbul",
    country: "TR",
  },
  {
    id: 4,
    name: "London",
    country: "GB",
  },
  {
    id: 5,
    name: "Ankara",
    country: "TR",
  },
  {
    id: 6,
    name: "Paris",
    country: "FR",
  },
  {
    id: 7,
    name: "Madrid",
    country: "ES",
  },
  {
    id: 8,
    name: "Amsterdam",
    country: "NL",
  },
  {
    id: 9,
    name: "Belgrade",
    country: "RS",
  },
  {
    id: 10,
    name: "Munich",
    country: "DE",
  },
  {
    id: 11,
    name: "Berlin",
    country: "DE",
  },
  {
    id: 12,
    name: "Chicago",
    country: "US",
  },
  {
    id: 13,
    name: "Brussels",
    country: "BE",
  },
  {
    id: 14,
    name: "Rome",
    country: "IT",
  },
  {
    id: 15,
    name: "Washington",
    country: "US",
  }
];
Onur Hangul
  • 317
  • 2
  • 8

4 Answers4

1

The problem was you have an array, to the array you need to call an api with the values inside the array.

so you need to wrap it using Promise.all, check the below code

happy coding :)

const cityName = [
  {
    id: 1,
    name: "New York City",
    country: "US",
  },
  {
    id: 2,
    name: "Vienna",
    country: "AT",
  },
  {
    id: 3,
    name: "Istanbul",
    country: "TR",
  },
  {
    id: 4,
    name: "London",
    country: "GB",
  },
  {
    id: 5,
    name: "Ankara",
    country: "TR",
  },
  {
    id: 6,
    name: "Paris",
    country: "FR",
  },
  {
    id: 7,
    name: "Madrid",
    country: "ES",
  },
  {
    id: 8,
    name: "Amsterdam",
    country: "NL",
  },
  {
    id: 9,
    name: "Belgrade",
    country: "RS",
  },
  {
    id: 10,
    name: "Munich",
    country: "DE",
  },
  {
    id: 11,
    name: "Berlin",
    country: "DE",
  },
  {
    id: 12,
    name: "Chicago",
    country: "US",
  },
  {
    id: 13,
    name: "Brussels",
    country: "BE",
  },
  {
    id: 14,
    name: "Rome",
    country: "IT",
  },
  {
    id: 15,
    name: "Washington",
    country: "US",
  }
];

let cities = []

Promise.all(cityName.map(city => 
  fetch(`https://api.weatherbit.io/v2.0/current?city=${city.name}&country=${city.country}&key=86e622607fbe4c2cb9f7f71889a4d48d`)))
 .then(resp => Promise.all(resp.map(r => r.json())))
 .then(entireData => {
    cities = entireData
    console.log(cities)
}) // in react you need to do this.setState({cities: entireData})
 
 
Learner
  • 8,379
  • 7
  • 44
  • 82
  • thanks DILEEP THOMAS ... its working great... but please give me some explanation for i would understand perfect.. why did you use Promise? – Onur Hangul Nov 06 '19 at 12:53
  • cool happy to hear :), so when you are calling an api the problem is its a future call so you need to somehow make it wait or you need a callback so when we are wrapping with promise.all it will execute through each one and once all the call get finish it will put the data into cities. You can read more on here, it will give you a better view of these kind of pblms https://stackoverflow.com/questions/46241827/fetch-api-requesting-multiple-get-requests – Learner Nov 06 '19 at 13:01
0

What exactly is the error you're getting?

George Ponta
  • 193
  • 1
  • 15
  • you can ask clarifications on comment section, dont post as an answer. – Learner Nov 06 '19 at 11:23
  • naturally i getting this error ``` cities.map is not a function ``` because cities is an object in the STATE but it is empty because i cannot push data which get from fetch() api – Onur Hangul Nov 06 '19 at 11:25
  • @GeorgePonta Yeah i can understand, even i started with 0 points. But dont use answer section for clarifications, because lot of people will be referring to the solution. So try solving and get points, Try it you will get it :) happy coding. – Learner Nov 06 '19 at 11:56
0

Are you getting the response first? if you got the response the do this.

const citySource = cityName.map((city) => {
    return fetch(https://api.weatherbit.io/v2.0/current?city=${city.name}&country=${city.country}&key=86e622607fbe4c2cb9f7f71889a4d48d)
      }).then(response => {
response.json()
this.setState({cities : response })
})
    console.log('citySource', citySource);
  }
vijay mano
  • 1
  • 1
  • 1
0

In state replace citites object with an array and replace this code.

  componentDidMount() {
    const citySource = cityName.map((city) => {
        return fetch("https://api.weatherbit.io/v2.0/current?city=${city.name}&country=${city.country}&key=86e622607fbe4c2cb9f7f71889a4d48d")
        .then(response => response.json())
        .then(data => { 
            this.setState(prevState => {
                cities : [...prevState.cities , data]
            });
         });
        });
}
Darshil Mehta
  • 122
  • 1
  • 6