'TypeError: Cannot read properties of undefined using reactjs and graphql

I'm creating a social media using RactJS, Mongoose, GraphQL and Apollo. When I try to fetch data from DB to be displayed in the home page I get an error saying TypeError: Cannot read properties of undefined (reading 'getPosts'). I search for the solution and tried a bunch of things and nothing worked

File structre

--client

----node_modules

----public

----src

------components

--------MenuBar.js

--------PostCard.js

------pages

--------Home.js

--graphQL

----resolvers

--------comments.js

--------index.js

--------posts.js

--------users.js

----typeDefs.js

--models

----Post.js

----User.js

Home.js

import React from 'react';
import { useQuery } from '@apollo/react-hooks';
import gql from 'graphql-tag';
import { Grid } from 'semantic-ui-react';


import PostCard from '../components/PostCard';

function Home() {
    const { loading, data: { getPosts: posts } } = useQuery(FETCH_POSTS_QUERY);

   return (
       <Grid columns={3}>
           <Grid.Row>
               <h1>Recent Posts</h1>
           </Grid.Row>
           <Grid.Row>
               {loading ? (
                   <h1>Loading posts..</h1>
               ) : (
                   posts && posts.map(post => (
                       <Grid.Column key={post.id}>
                           <PostCard post={post} />
                       </Grid.Column>
                   ))
               )}
           </Grid.Row>
       </Grid>
   )
}

const FETCH_POSTS_QUERY = gql`
    {
        getPosts{
            id
            body
            createdAt
            username
            likeCount
        likes {
            username
        }
        commentCount
        comments{
            id
            username
            createdAt
            body
        }
    }
    }
`;

export default Home;

posts.js

const { AuthenticationError, UserInputError } = require('apollo-server');

const Post = require('../../models/Post');
const checkAuth = require('../../util/check-auth');

module.exports = {
    Query: {
        async getPosts() {
            try {
                const posts = await Post.find().sort({ createdAt: -1 });
                return posts;
            } catch (err) {
                throw new Error(err);
            }
        },
        async getPost(_, { postId }) {
            try {
                const post = await Post.findById(postId);

                if(post) {
                    return post;
                } else {
                    throw new Error('Post not found')
                }
            } catch (err) {
                throw new Error(err);
            }
        }
    },
    Mutation: {
        async createPost(_, { body }, context) {
            const user = checkAuth(context);
            
            
            if(args.body.trim() === '') {
                throw new Error('Post body must not be empty');
            }

            const newPost = new Post({
                body,
                user: user.id,
                username: user.username,
                createdAt: new Date().toISOString()
            });
            const post = await newPost.save();

            context.pubsub.publish('NEW_POST', {
                newPost: post
            });

            return post;
        },
        async deletePost(_, { postId }, context) {
            const user = checkAuth(context);

            try {
                const post = await Post.findById(postId);
                if(user.username === post.username) {
                    await post.delete();
                    return 'Post deleted successfully';
                } else {
                    throw new AuthenticationError('Action not allowed');
                }
            } catch (err) {
                throw new Error(err);
            }
        },
        async likePost(_, { postId }, context) {
            const { username } = checkAuth(context);
      
            const post = await Post.findById(postId);
            if (post) {
                if (post.likes.find((like) => like.username === username)) {
                    // Post already likes, unlike it
                    post.likes = post.likes.filter((like) => like.username !== username);
                } else {
                    // Not liked, like post
                    post.likes.push({
                        username,
                        createdAt: new Date().toISOString()
                    });
                }
      
                await post.save();
                return post;
            } else throw new UserInputError('Post not found');
          }
        },
    Subscription: {
        newPost: {
            subscribe: (_, __, { pubsub }) => pubsub.asyncIterator('NEW_POST')
        }
    }
}

When I console.log(data) before implementing the data: {getPosts: posts} it runned smoothly returning an object as expected but after that the app crashed.



Solution 1:[1]

maybe try this:

const { loading, data } = useQuery(FETCH_POSTS_QUERY)
const { getPosts: posts } = {...data}

or another way is to do this:

const { loading, data: { getPosts: posts } = {} } = useQuery(FETCH_POSTS_QUERY)

Let me know if it still doesn't work leave a comment below.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1