1

在我的 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

请帮忙。提前致谢。

4

2 回答 2

2

今天犯了同样的错误,我花了一点时间找到正确的解决方案。我用同样的问题看了你的问题,但没有解决我的问题。一段时间后,我注意到我argsconnectionFromPromisedArray电话不见了。因此,要解决您的问题,请尝试更改:

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
      }
    },
于 2016-12-13T06:52:24.747 回答
0

更新#1:

问题在于定义中posts字段的实现。userType

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

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

顺便说一句,你不会通过query职位。如果你不提供query参数,你应该只使用args: {...connectionArgs},.


看起来你已经使用过 Mongoose 库。如果是这样的话,一个明显的问题是getPosts函数的实现。exec本身返回一个 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();
}

如果您在修复此问题后遇到进一步的问题,请告诉我。

于 2016-07-23T12:13:02.460 回答