So this is my code (react
, redux-toolkit
) and I am getting that error.
import { useState, useEffect } from "react";
import { useSelector, useDispatch } from "react-redux";
import styles from "./styles.module.css";
import { getCurrentWeather } from "../../Redux/Reducers/currentWeatherSlice";
import { getUserPosition } from "../../Redux/Reducers/userPositionSlice";
// URLFor the icons
// https://openweathermap.org/img/wn/${}.pngs
function CurrentWeather() {
const dispatch = useDispatch();
const currentWeather = useSelector(
(state) => state.currentWeather.currentWeather
);
const userPosition = useSelector((state) => state.userPosition.userPosition);
const [query, setQuery] = useState("");
const [x, setX] = useState(null);
const [y, setY] = useState(null);
//Get user's Position
useEffect(() => {
const successHandler = (position) => {
setX(position.coords.latitude);
setY(position.coords.longitude);
};
navigator.geolocation.getCurrentPosition(successHandler);
if (x && y !== null) {
dispatch(getUserPosition({ x, y }));
}
}, [dispatch, x, y]);
const handleCitySearch = (e) => {
setQuery(e.target.value);
};
const handleForm = (e) => {
e.preventDefault();
};
const handleCityFetch = () => {
dispatch(getCurrentWeather(query));
setQuery("");
};
console.log(userPosition);
return (
<div className={styles.container}>
<h1>CurrentWeather</h1>
<div className={styles.currentWeather_container}>
<div className={styles.input_container}>
<form onSubmit={handleForm} className={styles.form}>
<input
value={query}
type="text"
placeholder="Search City"
onChange={handleCitySearch}
/>
<button onClick={handleCityFetch}>Go</button>
</form>
</div>
<div className={styles.top_section}>
{x && y && userPosition && (
<>
<div>
<p>{userPosition.name}</p>
<p>{userPosition.visibility}</p>
</div>
<div>
<span>{userPosition?.main.temp}</span>
<span>°C</span>
</div>
</>
)}
</div>
</div>
</div>
);
}
export default CurrentWeather;
Even though it works as expected with the userPosition.name
when I try to render userPosition.main.temp
I'm getting the error.
I am not sure if its a redux state problem or that I'm trying to render before I get the data (even though it seems that I do have the data).
I've tried multiple solutions such as moving the state for the userPosition
to its own slice, using the Optional Chaining operator on userPosition
, also I had a bunch of console logs everywhere but I can't find my mistake.
You've placed the null-check on the wrong object. The error is informing you that userPosition.main
is undefined. This access is fine though, same as userPosition.name
and userPosition.visibility
. No error is thrown since userPosition
is defined. The issue arises when userPosition.main
is undefined and the code attempts to access the temp
property
{x && y && userPosition && (
<>
<div>
<p>{userPosition.name}</p> // ok, value is undefined
<p>{userPosition.visibility}</p> // ok, value is undefined
</div>
<div>
<span>
{userPosition?.main.temp} // not ok, accessing undefined object
</span>
<span>°C</span>
</div>
</>
)}
Since the code has already checked above that to ensure userPosition
is truthy, move the null-check onto the potentially null/undefined main
property.
{x && y && userPosition && (
<>
<div>
<p>{userPosition.name}</p> // ok, value is undefined
<p>{userPosition.visibility}</p> // ok, value is undefined
</div>
<div>
<span>
{userPosition.main?.temp} // ok, value is undefined or temp
</span>
<span>°C</span>
</div>
</>
)}