skip to Main Content

I’m trying to make a weather app in RN. This is my code so far:

import { StatusBar } from 'expo-status-bar';
import { useEffect, useState } from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { Button } from 'react-native';
import axios from "axios";
import * as Location from "expo-location"
import WeatherScreen from './Screens/WeatherScreen';


export default function App() {
const [weatherData,setWeatherData] = useState()
const [city,setCity]= useState()
const [dataLoaded,setDataLoaded]= useState()

const fetchWeatherDara = async() =>{
  try{

    setDataLoaded(false)
    const response = await  fetch("https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid=key")
    if(response.status == 200){
      const data = await response.json()
      setWeatherData(data)
    }
    else{
      setDataLoaded()
    }
    setDataLoaded(true)
  }catch(error){
    console.log(error)
  }
  console.log(weatherData)

  if(dataLoaded){
    const reverseAddress = await Location.reverseGeocodeAsync({
      longitude:weatherData.coord.lon,
      latitude:weatherData.coord.lat
    })
    setCity(reverseAddress[0].city)
    console.log(city)
  }
}

useEffect(() =>{
  fetchWeatherDara()
},[])

  if(dataLoaded == false){
    return (
      <View style={styles.container}>
            <Text>Loading....</Text>
       </View>
  )
  }
  
  return (
      <View style={styles.container}>
          <WeatherScreen weatherData={weatherData}/>
       </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#1C9CF6',
    alignItems: 'center',
    justifyContent: 'center',
  },
  cityName:{  
    color:"white",
    fontWeight:'bold',
    fontSize:40
  },
  currentTemp:{
    color:"white",
    fontSize:100,
    fontWeight:200,
    
  },
  highLow:{
    color:"white",
    fontSize:20
  }
});

import { StyleSheet, Text, View } from 'react-native'
import React from 'react'

const WeatherScreen = ({weatherData}) => {
    const {
        name,
        timezone
    } = weatherData;
  return (
    <View>
      <Text>{name}</Text>
    </View>
  )
}

export default WeatherScreen

const styles = StyleSheet.create({})

When I launch App.js on the first try, I get an error saying "Cannot read propety of ‘name’ defined (from my WeatherScreen componenet).

When I remove {name} and the object in my WeatherScreen code, the app then refreshes and seems to work fine. I want the app to run on launch without getting the error.

This is the JSON I’m extracting data from, using random lat and lon:
JSON

2

Answers


  1. That is because you don’t have data when the component first loads, it is still being fetched. One thing you can do is check the object before rendering.

    const WeatherScreen = ({weatherData}) => {
    
        // no data yet, just return. 
        // This should re-render when the state updates
        if (weatherData === null) {
            return;
        }
    
        const {
            name,
            timezone
        } = weatherData;
      return (
        <View>
          <Text>{name}</Text>
        </View>
      )
    }
    
    Login or Signup to reply.
  2. Try below

    import { StyleSheet, Text, View } from 'react-native'
    import React from 'react'
    
    const WeatherScreen = ({weatherData}) => {
    const {
        name,
        timezone
    } = weatherData;
    return (
    <View>
      <Text>{name!=undefined && name}</Text>
    </View>
    )
    }
    
    export default WeatherScreen
    
    const styles = StyleSheet.create({})
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search