Search code examples
reactjsgraphqlapollo

useQuery - can not read properties of undefined


Initial query returns undefined, but all subsequent calls return valid data. If I try to map my response, an error is thrown:

can not read properties of undefined

and the whole app is down. How do i fix this?

import { useQuery } from "@apollo/client";
import { Component } from "react";
import { useState, useEffect } from "react";

import GET_PRODUCTS from '../../server/getProducts';

import './productList.sass';

class ProductList extends Component {

    render() {
        return (
            <RenderProducts />
        );
    }
}

const RenderProducts = () => {
    
    const { data } = useQuery(GET_PRODUCTS);
    console.log(data.products.map(product => console.log(product)));
    const products = data.products.map((product) => {
        return (
            <li className="productList__item">
                <img className="productList__item-img" src={product.mainImage.url} alt={product.title} />
                    <div className="productList__item-descr">
                        <div className="productList__item-title">{product.title}</div>
                        <div className="productList__item-price">{product.price} $</div>
                </div>
            </li>
        )
    })
    return <ul>{products}</ul>
}

export default ProductList;

error img


Solution

  • If I try to map my response, an error is thrown: and the whole app is down. How do i fix this?

    You'll need to render something when the query is in a loading state. You can take advantage of the loading and error properties of useQuery hook. Here's a sample:

    const RenderProducts = () => {
        
        const { data, loading, error } = useQuery(GET_PRODUCTS);
    
        if(loading) return <div>loading...</div>
        if(error) return <div>cannot render products...something went wrong</div>
    
        // if the query has finished loading products and there's no error, 
        // You can access data.products
        // and write your logic 
        console.log(data.products.map(product => console.log(product)));
        const products = data.products.map((product) => {
            return (
                <li className="productList__item">
                    <img className="productList__item-img" src={product.mainImage.url} alt={product.title} />
                        <div className="productList__item-descr">
                            <div className="productList__item-title">{product.title}</div>
                            <div className="productList__item-price">{product.price} $</div>
                    </div>
                </li>
            )
        })
        return <ul>{products}</ul>
    }