Search code examples
reactjsreduxreact-hooksrtk-query

RTK Query call sometimes returns "undefined"


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.


Solution

  • 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.