My React App pulls data from a Djano REST API through the api.js file below.
api.js
const URLS = {
PRODUCTS: "http://127.0.0.1:8000/api/products/",
PRODUCT: (id) => `http://127.0.0.1:8000/api/products/${id}`,
};
const wrappedFetch = (...args) => {
return fetch(...args).then((res) => {
return res.json();
});
};
const get = (url) => wrappedFetch(url);
// PRODUCT API
const loadProducts = () => get(URLS.PRODUCTS);
const loadProduct = (id) => get(URLS.PRODUCT(id));
export {
loadProducts,
loadProduct,
};
The data does not successfully render at its first load and identifies an issue in my useAllProducts.js file below.
import { useQuery } from "react-query";
import { loadProducts } from "./api/api";
function useAllProducts() {
const { data = [] } = useQuery("products", loadProducts);
console.log(data)
return data.products.map(({ id }) => id);
}
export default useAllProducts;
The error is undefined is not an object (evaluating 'data.products.map')
At useAllProduts.js
Once I change return data.products.map(({ id }) => id);
to return data.map(({ id }) => id);
and back again to return data.products.map(({ id }) => id);
, the products render successfully.
Replacing the above with
return data.products && products.map(({ id }) => id);
does not solve the error.
Also when I refresh the page, the same error persists (undefined is not an object (evaluating 'data.products.map'
). I think my App renders data before it’s populated and possibly needs to add a condition or async/await in my api.js.
How do I solve this: I have tried adding async/await, but I feel I blundered and therefore did not work.
I know there are similar questions, but my api.js file is quite different.
Please help me.
2
Answers
return data.products && products.map(({ id }) => id);
is incorrect becauseproducts
is undefined inproducts.map
. You’d want to do something more likereturn data.products && data.products.map(({ id }) => id);
.On the initial render when data has yet to be fetched (and cached)
data.products
is undefined. When you change the code todata.map(({ id }) => id);
and back and it works, it’s likely that the hook is able to read the cached response anddata.products
is defined.If you are expecting the fetched data to have a
products
property that is the array, then you can provide a better fallback value, and use a null-check on the potentially undefined property accesses.Examples: