0

Working on an app using the google maps API for geolocation with Reactjs. My aim right now is to simply render the entire JSON data to the window (will be used later). No errors, but nothing is rendering to the page. Am I trying to access the data inccorrectly?

class App extends Component {
  constructor () {
    super();
    this.state = {
      isLoaded: false,
      results: {}
    };
  }

  componentDidMount() {
    fetch(geo_url)
    .then(res => res.json())
    .then(
      (result) => {
        this.setState({
          isLoaded: true,
          results: result.results
        });
      },
      (error) => {
        this.setState({
          isLoaded: true,
          error
        });
      }
    )
  }


  render() {
    const {error, isLoaded, results} = this.state;
      if (error) {
        return <div>Error: {error.message} </div>;
      } else if (!isLoaded) {
        return <div>Loading...</div>;
      } else {
      return (
        <div className="App">
          Location Data:
          {results.geometry}
        </div>
      );
  }
  }
}

Below is a sample of the JSON i'm trying to access:

{
    "results": [
        {
            "address_components": [
                {
                    "long_name": "1600",
                    "short_name": "1600",
                    "types": [
                        "street_number"
                    ]
                },
                {
                    "long_name": "Amphitheatre Parkway",
                    "short_name": "Amphitheatre Pkwy",
                    "types": [
                        "route"
                    ]
                },
                {
                    "long_name": "Mountain View",
                    "short_name": "Mountain View",
                    "types": [
                        "locality",
                        "political"
                    ]
                },
                {
                    "long_name": "Santa Clara County",
                    "short_name": "Santa Clara County",
                    "types": [
                        "administrative_area_level_2",
                        "political"
                    ]
                },
                {
                    "long_name": "California",
                    "short_name": "CA",
                    "types": [
                        "administrative_area_level_1",
                        "political"
                    ]
                },
                {
                    "long_name": "United States",
                    "short_name": "US",
                    "types": [
                        "country",
                        "political"
                    ]
                },
                {
                    "long_name": "94043",
                    "short_name": "94043",
                    "types": [
                        "postal_code"
                    ]
                }
            ],
            "formatted_address": "1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA",
            "geometry": {
                "location": {
                    "lat": 37.422617,
                    "lng": -122.0853839
                },
                "location_type": "ROOFTOP",
                "viewport": {
                    "northeast": {
                        "lat": 37.4239659802915,
                        "lng": -122.0840349197085
                    },
                    "southwest": {
                        "lat": 37.4212680197085,
                        "lng": -122.0867328802915
                    }
                }
            },
            "place_id": "ChIJ2eUgeAK6j4ARbn5u_wAGqWA",
            "plus_code": {
                "compound_code": "CWF7+2R Mountain View, California, United States",
                "global_code": "849VCWF7+2R"
            },
            "types": [
                "street_address"
            ]
        }
    ],
    "status": "OK"
}
Red Rabbit
  • 115
  • 1
  • 11

3 Answers3

1

First render occurs before results are retrieved. Check in render() whether results exist already. If not, display a 'loading' message.

In addition to that, fix your handling of error while trying to retrieve data. You are setting a state.error variable which was not defined. Then, in render, display an error message if loading is done but there is an error.

Yossi
  • 5,577
  • 7
  • 41
  • 76
  • Added error message handlers, but now it's just a blank page. No more undefined errors though – Red Rabbit Nov 23 '18 at 19:09
  • First of all, put the if (!loaded) before if (error). This is the logical order. Also, initialize state.error to false. Then, check errors as explained here: https://stackoverflow.com/a/38236296/5532513 – Yossi Nov 24 '18 at 05:26
0

First, you have to do :

 <div className="App">
     {this.state.results.geometry}
  </div>

or

     render() {
          const {results} = this.state
          return (
            <div className="App">
              {results.geometry}
            </div>
          );
      }
}

But Like @Yossi saids, you result are not defined in you first render. That's why you have : "results not defined". You can use "lodash" to force your render. It's works even if I don't know if it's a good practice

You can test :

import _ from 'lodash';

     render() {
          const {results} = this.state
          return (
          {!_.isEmpty(results) && 
            <div className="App">
              {results.geometry}
            </div>             
            }

          );
      }

It should be works :)

PS : sorry for my bad english ;)

hollowspy
  • 11
  • 4
0

You can set in state a key for error: false.

In componentDidMount its better to use then and catch for errors

  componentDidMount() {
fetch(geo_url)
.then(res => res.json())
.then(
  (result) => {
    this.setState({
      isLoaded: true,
      results: result.results
    });
  },
  (error) => {
    this.setState({
      isLoaded: true,
      error
    });
  }
).catch(error) {
   this.setState({
   isLoaded: true,
   error
  })
 }

}

Fernando Colom
  • 337
  • 1
  • 3