I'm trying to call the data key from the hook call useGetSomeProjectsQuery(). This is within the hook useProjects().
import { useState, useEffect } from "react";
import { useGetSomeProjectsQuery } from "./projectsApi";
export default function useProjects() {
const [page, setPage] = useState(1);
const [title, setTitle] = useState("");
const [languages, setLanguages] = useState("");
const [withDetails, setWithDetails] = useState([]);
const newProjects = useGetSomeProjectsQuery(page, languages, title);
const getprojects = newProjects.data.projects;
useEffect(() => {
setWithDetails(
getprojects.map((project) => {
return { ...project, details: false };
})
);
}, [getprojects]);
return { withDetails };
}
Sometimes the data appears right when I open the page. Other times, it returns "undefined". This is without me having made changes to the code.
More specifically, it says
Cannot read properties of undefined (reading 'projects')
In reference to
const getprojects = newProjects.data.projects;
I figured the issue was timing, so I tried using async/await
export default async function useProjects(){
const newProjects = useGetSomeProjectsQuery(page, languages, title);
const getprojects = async newProjects.data.projects;
}
But that didn't work. I also tried using setTimeout on the "getprojects" variable, but that failed as well. Finally, I checked if my API itself was working, and it opens just fine https://mernportfolio.onrender.com/api/v1/projects
EDIT: The same goes for trying newProjects.isSuccess. When I set it, so the data appears only if newProjects.isSuccess is true, the error goes away, but the data doesn't appear.
fetching the data is an async job which means when javascript reads your code it will pass the line of async code and keep reading the next line.
so when javascript reaches the console.log
the data is undefined
and sometimes the network is fast and data loads before the javascript reaches the console.log
.
so you need to handle this.
javascript have many approaches in this area like callback
functions or promises
you should know async await
and basically making a request to the server is just a promise
under the hood.
why is data is undefined
instead of null
?
that is because javascript has mainly 2 stages of reading the JS code.
one is the creation phase and the second is the execution phase.
during the creation phase, javascript allocates memory for all of your variables and sets the value of variables to the undefined
and in the execution phase, it actually assigns the real value to the variable.
so the value filled with data after request fulfilled.
in your case
export default function useProjects(){
const { data, isLoading, isFetching} = useGetSomeProjectsQuery({page,
languages, title});
if ( isLoading || isFetching ) return <p>Loading ... </p>
// here do something with data
}
and remember to pass all query params as a single object to the queryHook.