I have an error when fetching data on firebase realtime database with react js hook. When i lopping data with map, error is coming "is undefined" but i saw on the console log data is success.
I think the error because looping code execute before fetching finish
this is fetch code
const [firebaseDb, setFirebaseDb] = useState(database);
const [data, setData] = useState([]);
const [loading, setLoading] = useState(false);
const getData = async () =>{
try {
const dbRef = firebaseDb;
let snapshot = await get(child(dbRef, `menu`))
if (snapshot.exists()) {
console.log(snapshot.val());
setData(snapshot.val());
setLoading(false);
} else {
setData({});
setLoading(false);
console.log("No data available");
}
} catch(e){
setLoading(false)
console.log(e.message);
}
}
useEffect(() => {
setLoading(true);
getData()
}, []);
this is lopping code
{
loading ? (
<Row><p>Loading ... !</p></Row>
) : (
<Row>
{
data.appetizer.map((apper, index) => {
return (
<Col key={index} lg='6' className="p-3">
<div className="menu-list p-3">
<h5>{apper.name}</h5>
<h4>{apper.price}k</h4>
<p className="mb-0">{apper.desc}</p>
</div>
</Col>
)
})
}
</Row>
)
}
CodePudding user response:
Your data
variable is an array at initial, so it doesnt has appetizer
attribute. Use data.map(...)
instead. ( try to pass to setData
with an array )
Of course rendering will always execute before fetching finish. All you need is checking typeof data.length > 0
before render mapping ---- or just set initial value of loading
into true.
It should be something like this:
const [loading, setLoading] = useState(true);
Or
loading || data.length === 0 ? (
<Row><p>Loading ... !</p></Row>
)