在实现 react-relay 时无法读取未定义的 属性 'after'

Cannot read property 'after' of undefined in implementing react-relay

在我的 nodejs 应用程序中

这是我的 schema.js 文件

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

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}`

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

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

但我在终端中遇到以下错误

    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 字段的实现中。

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

解构 args 时,Rest parameter connectionArgs 应该放在最后。 query 应该排在第一位。因为rest参数使用错误,发现connectionArgsundefined.

顺便说一下,你没有通过 query 的帖子。如果您不提供 query 参数,您应该只使用 args: {...connectionArgs},.


看来您使用过 Mongoose 库。如果是这样,一个明显的问题是 getPosts 函数的实现。 exec 本身 returns a promise。因此,它不需要包装在 Promise 中。替换这个

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();
}

如果您在修复此问题后遇到更多问题,请告诉我。

今天犯了同样的错误,我花了一点时间才找到正确的解决方案。我用同样的问题看了你的问题,但没有解决我的问题。一段时间后,我发现我的 connectionFromPromisedArray 电话中缺少 args。因此,要解决您的问题,请尝试更改此设置:

posts: {
      type: postConnection,
      args: {
        ...connectionArgs,
        query: { type: GraphQLString }
      },
      resolve: (rootValue, args) => { // <== here is added args attribute
        return connectionFromPromisedArray(getPosts(rootValue), args) // <== here is added args attribute
      }
    },