5

import React, {Component} from 'react';
import './App.css';
import axios from 'axios';

export default class App extends Component {

    constructor() {
        super();
        this.state = {
            weather: []
        };
    }
componentDidMount (){

  this.search();
}
    search = () => {

        axios.get("http://api.openweathermap.org/data/2.5/weather?q=Houston&APPID=f2327cca8f3d665f4c9f73b615b294ed")
        .then(res => {

            this.setState({weather: res.data});

        }).catch(error => {
            console.log('Error from fetching data', error);
        })
    }

    render() {
    console.log(this.state.weather);
    const weathermap = this.state.weather.map( (maps) =>{
      {maps.wind.speed}
});

        return (
            <div className="container">
                <div className="row">
                    <div className="col-md-4 col-md-offset-4">
                        <div className="weather">
                            <div className="current">
                                <div className="info">
                                    <div>&nbsp;</div>
                                    <div className="city">
                                        <small>
                                            <small>CITY:</small>
                                        </small>
                                        {this.state.weather.name}</div>
                                    <div className="temp">67&deg;
                                        <small>F</small>
                                    </div>
                                    <div className="wind">
                                        <small>
                                            <small>WIND:{weathermap}</small>
                                        </small>

                                        </div>
                                    <div>&nbsp;</div>
                                </div>
                                <div className="icon">
                                    <span className="wi-day-sunny"></span>
                                </div>
                            </div>
                            <div className="future">
                                <div className="day">
                                    <h3>Mon</h3>
                                    <p>
                                        <span className="wi-day-cloudy"></span>
                                    </p>
                                </div>
                                <div className="day">
                                    <h3>Tue</h3>
                                    <p>
                                        <span className="wi-showers"></span>
                                    </p>
                                </div>
                                <div className="day">
                                    <h3>Wed</h3>
                                    <p>
                                        <span className="wi-rain"></span>
                                    </p>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

        );
    }
}

I am getting a "this.state.weather.map is not a function" error. I am fetching data from weather api. I got the name from api displayed ok. api call it self is ok is success too. here how the api looks like in console enter image description here

here is the code

jsPlayer
  • 1,195
  • 7
  • 32
  • 56
  • If `this.state.weather` is a JS object, then it won't have the method `.map` to it. However, if it's a `Immutable.Map`, then yes it would have it. – Suthan Bala Mar 24 '17 at 01:13
  • `this.setState({ weather: this.state.weather.concat([{ ...res.data }]) })` – Rei Dien Mar 24 '17 at 01:36
  • would I display the date the same way I use setState with concat ? like this const weathermap = this.state.weather.map( (maps) =>{ {maps.wind.speed} – jsPlayer Mar 24 '17 at 02:38

3 Answers3

6

You are instantiating the app by saying this.state = { weather: []};. However, When you say this.setState({weather: res.data}), you are overriding the this.state.weather to a JavaScript object rather than array, thus the .map is not available anymore.

You can achieve what you're trying to do by simply const weathermap = this.state.weather.wind.speed

Suthan Bala
  • 3,209
  • 5
  • 34
  • 59
  • being new to react , that was my above statement in the beginning . but it throw a Cannot read property 'speed' of undefined If I do const weathermap = this.state.weather.wind.speed. when directly insert this.state.weather.wind.speed inside WIND, then I get the "Objects are not valid as a React child (found: object with keys {speed, deg, gust}). If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object) from the React add-ons. Check the render method of `App`." erro – jsPlayer Mar 24 '17 at 01:33
5

this.state.weather is a javascript object so .map is not available you can use

Object.Keys(YourObject).map() 
Amir Tahani
  • 688
  • 5
  • 13
1

You should do conditional check and then do .map like

.map with return syntax

const { weather } = this.state;
const weathermap = weather && weather.map(maps => {
      return <span>{maps.wind && maps.wind.speed}</span>
});

.map without return syntax

const { weather } = this.state;
const weathermap = weather && weather.map(maps => (
     <span>{maps.wind && maps.wind.speed}</span>
));
Hemadri Dasari
  • 32,666
  • 37
  • 119
  • 162