在实现react-relay时无法读取未定义的属性"after" [英] Cannot read property 'after' of undefined in implementing react-relay

查看:73
本文介绍了在实现react-relay时无法读取未定义的属性"after"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的nodejs应用程序中

In my nodejs application

这是我的schema.js文件

here is my schema.js file

import {
  GraphQLBoolean,
  GraphQLID,
  GraphQLInt,
  GraphQLList,
  GraphQLNonNull,
  GraphQLObjectType,
  GraphQLSchema,
  GraphQLString,
} from 'graphql';

import {
  connectionArgs,
  connectionDefinitions,
  connectionFromArray,
  connectionFromPromisedArray,
  cursorForObjectInConnection,
  fromGlobalId,
  globalIdField,
  mutationWithClientMutationId,
  nodeDefinitions,
  toGlobalId,
} from 'graphql-relay';

import {
  User,
  getUser,
  getPosts,
  createpost,
} from '../data/database.js';

var { nodeInterface, nodeField } = nodeDefinitions(
  (globalId) => {
    var { type, id } = fromGlobalId(globalId);
    if (type === 'User') {
      return getUser(id);
    }else if (type === 'Post') {
      return getPosts(id);
    }
    return null;
  },
  (obj) => {
    if (obj instanceof User) {
      return userType;
    }else if (obj instanceof Post) {
      return postType;
    }
    return null;
  }
);

var userProfileImageType = new GraphQLObjectType({
  name: 'ProfileImage',
  fields: {
    full: {
      type: GraphQLString
    }
  }
});

var userLocalAccountType = new GraphQLObjectType({
  name: 'Local',
  fields: {
    email: {
      type: GraphQLString
    }
  }
});

var userFacebookAccountType = new GraphQLObjectType({
  name: 'Facebook',
  fields: {
    id: {
      type: GraphQLString
    },
    displayName: {
      type: GraphQLString
    }
  }
});

var userGoogleAccountType = new GraphQLObjectType({
  name: 'Google',
  fields: {
    id: {
      type: GraphQLString
    },
    displayName: {
      type: GraphQLString
    }
  }
});

var postType = new GraphQLObjectType({
  name: 'Post',
  fields: {
    id: globalIdField('Post'),
    title: {
      type: GraphQLString
    },
    userId: globalIdField('User'),
    content: {
      type: GraphQLString
    }
  },
  interfaces: [nodeInterface]
});

/**
 * Define your own connection types here
 */

const {
  connectionType: postConnection,
  edgeType: postEdge,
} = connectionDefinitions({name: 'Post', nodeType: postType});

let createPostMutation = mutationWithClientMutationId({
    name: 'CreatePost',

    inputFields: {
      title: { type: new GraphQLNonNull(GraphQLString) },
      content: { type: new GraphQLNonNull(GraphQLString) },
      userId: { type: new GraphQLNonNull(GraphQLString) },
    },

    outputFields: {
      postEdge: {
        type: postConnection,
        resolve: (obj) => ({ node: obj, cursor: obj.insertedId })
      },
    },

    mutateAndGetPayload: ({title, content,userId}) => {
      console.log({title, content,userId})
      return createpost({title, content,userId})
    }
  });

var userType = new GraphQLObjectType({
  name: 'User',
  fields: {
    id: globalIdField('User'),
    fullName: {
      type: GraphQLString,
      description: "Users' Full Name"
    },
    isPremium: {
      type: GraphQLBoolean,
      description: "Does the user have premium subscription?"
    },
    currentPostCount: {
      type: GraphQLInt,
      description: "User's current total post"
    },
    images: {
      type: userProfileImageType,
      description: "User's profile image links"
    },
    local: {
      type: userLocalAccountType,
      description: "User's local account info"
    },
    facebook: {
      type: userFacebookAccountType,
      description: "User's Facebook account info"
    },
    google: {
      type: userGoogleAccountType,
      description: "User's Google Plus account info"
    },
    posts: {
      type: postConnection,
      args: {
        ...connectionArgs,
        query: { type: GraphQLString }
      },
      resolve: (rootValue) => {
        return connectionFromPromisedArray(getPosts(rootValue))
      }
    },
  },
  interfaces: [nodeInterface]
});

var Root = new GraphQLObjectType({
  name: 'Root',
  fields: () => ({
    user: {
      type: userType,
      resolve: (rootValue, _) => {
        return getUser(rootValue)
      }
    },
  })
})

export var schema = new GraphQLSchema({
  query: Root,
  mutation: new GraphQLObjectType({
    name: 'Mutation',
    fields: () => ({
      createPost: createPostMutation
    })
  })
});

和下面是我的database.js

and below is my database.js

import User from './models/userModel'
import Post from './models/postModel'

export { User }
export { Post }

export function getUser(user) {
  let validUser = false
  if (user.local || user.facebook || user.google) {
    validUser = true
  }
  return new Promise((resolve, reject) => {
    if (validUser) {
      let localEmail = user.local.email || ""
      let googleID = user.google.id || ""
      let facebookID = user.facebook.id || ""
      User.findOne({
        $or: [
          { "local.email": localEmail },
          { "facebook.id": facebookID },
          { "google.id": googleID }
        ]
      }, function(err, existingUser) {
        if (err || !existingUser) {
          resolve({})
        } else {
          resolve(existingUser)
        }
      });
    } else {
      resolve({})
    }
  })
}

export function getPosts(user) {
  return new Promise((resolve, reject) => {
     Post.find({}).exec({}, function(err, posts) {
        resolve(posts)
      });

  })
}

export function createpost({title, content,userId}){
  return new Promise((resolve, reject) => {
      const blogPostModel = new Post({title, content,userId});
      const newBlogPost = blogPostModel.save();
      if (!newBlogPost) {
        throw new Error('Error adding new blog post');
      }
       resolve({})
  })
}

我正在吸引用户

Relay.QL `query { user}`

我想与用户一起获取所有帖子

I want to fetch all posts along with user

Relay.QL 'query{
  user {
    id,
    posts(first: 3) {
      edges {
        node {
          id,
          title
        }
      }
    }
  }
}'

但是我在终端中遇到错误

but i am getting below error in terminal

    Failed to execute query `UserQueries` for the following reasons:

1. Cannot read property 'after' of undefined
   le {id,displayName},_posts3KBCho:posts(first:3) {edges {node

请帮助.预先感谢.

推荐答案

更新#1:

问题出在 userType 定义中的 posts 字段的实现中.

The problem is in the implementation of posts field in userType definition.

posts: {
  type: postConnection,
  args: {
    ...connectionArgs,
    query: { type: GraphQLString }
  },
  resolve: (rootValue) => {
    return connectionFromPromisedArray(getPosts(rootValue))
  }
},

在分解 args 时,

While destructuring args, the Rest parameter connectionArgs should come in the end. query should come first. Because of the wrong use of rest parameters, connectionArgs is found undefined.

顺便说一句,您不会通过 query 来获取帖子.如果不提供 query 参数,则应仅使用 args:{... connectionArgs},.

By the way, you don't pass query for posts. If you don't provide query argument, you should just use args: {...connectionArgs},.

好像您已经使用过Mongoose库.如果是这样,一个明显的问题就是 getPosts 函数的实现. exec 本身返还诺言.因此,它不需要包装在Promise中.取代这个

Looks like you've used Mongoose library. If that's the case, one obvious problem is in the implementation of getPosts function. exec itself returns a promise. So, it doesn't need to be wrapped in a Promise. Replace this

export function getPosts(user) {
  return new Promise((resolve, reject) => {
     Post.find({}).exec({}, function(err, posts) {
        resolve(posts)
      });

  })
}

与此

export function getPosts(user) {
    return Post.find({user_id: user._id}).exec();
}

解决此问题后,如果您遇到其他问题,请告诉我.

Please let me know if you face further problems after fixing this.

这篇关于在实现react-relay时无法读取未定义的属性"after"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆