【问题标题】:Cannot read property 'save' of null error when using update mutaiton in GraphQL在 GraphQL 中使用更新突变时无法读取空错误的属性“保存”
【发布时间】:2021-06-23 22:43:22
【问题描述】:

我正在学习 GraphQL,并正在使用 Node.js 开发联系人管理器应用程序,我的数据库是 MongoDB。添加和删​​除突变工作正常,但每当我尝试运行更新突变时,它都会引发错误。我在运行 Windows 10 20H2 的 Windows 机器上。文本编辑器是 VS Code。终端是windows powershell,我使用npm来运行程序。

这是我的./graphql.js 文件

    const express = require('express');
    const {contact_book} = require('../models/contact_book');
    const {User} = require('../models/user_registration');
    
    
    const typeDefs = `type Query {
        getContact(id: ID!): contact_book
        getContacts: [contact_book]
        getUser(id: ID!): User
        getUsers: [User]
      }
      type contact_book {
        id: ID!
        name: String!
        email: String
        phone: String!
      }
      type User {
        id: ID!
        name: String!
        password: String!
        email: String
        phone: String!
      }
      type Mutation {
        addUser(name: String!, password: String!, phone: String!, email: String!): User!,
        updateUser(id:ID!, name: String, password: String, phone: String, email: String):User,
        deleteUser(id: ID!): String,
        addContact(name: String!, phone: String!, email: String!): contact_book!,
        updateContact(id: ID!, name: String, phone: String, email: String):contact_book,
        deleteContact(id: ID!): String
        
      }`
    
    const resolvers = {
      Query: {
        getUsers: ()=> User.find(),
        getUser: async (_,{id}) => {
          const user = await User.findById(id);
          return ("User Created",user);
        },
        getContacts: ()=> contact_book.find(),
        getContact: async (_,{id}) => {
          const contact = await contact_book.findById(id);
          return contact;
        }
      },
      Mutation: {
        addUser: async (_, { name, password, email, phone }) => {
          const user = new User({name, password, email, phone});
          await user.save();
          return user;
        },
        updateUser: async(_, args)=>{
          const user = await User.findOneAndUpdate({id: args.id}, 
            { 
              name: args.name, 
              password: args.password,
              email: args.email, 
              phone: args.phone
            },{new: true});
          await user.save();
          return user; 
        },
        deleteUser: async (_, {id}) => {
          const user = await User.findByIdAndRemove(id);
          return ('User deleted');
        },
        addContact: async(_, { name, email, phone })=>{
          const contact = new contact_book({ name, email, phone });
          await contact.save();
          return contact
        },
        updateContact: async(_, args)=>{
          const contact = new contact_book.findOneAndUpdate({id: args.id},
            {
              name: args.name,
              email:args.email, 
              phone: args.email 
            },{new: true});
          await contact.save();
          return contact;
        },
        deleteContact: async(_, {id})=>{
          const contact = await contact_book.findByIdAndRemove(id);
          return ('Contact deleted');
        }
      }
    }
    
    module.exports = {typeDefs, resolvers,};

这是我的./index.js 文件。在我第一次使用 REST 实现此代码时,请忽略到 REST API 的路由。

const { GraphQLServer } = require('graphql-yoga');
const graphqlHTTP = require('express-graphql').graphqlHTTP;
const mongoose = require('mongoose')
const express = require('express');
const expressPlayground = require('graphql-playground-middleware-express').default;
const register = require('./routes/user_registration');
const login = require('./routes/user_login');
const contact = require('./routes/contact_book');
const {typeDefs, resolvers} = require('./graphql/graphql');

const app = express();
app.use(express.json());


mongoose.connect('mongodb://localhost:27017/ContactBook')
    .then(()=> console.log('Connected to db'))
    .catch(err=> console.log('Could not connect' ));

console.log('Running on port 4000');

/*const port = 4000;
app.listen(port, ()=>console.log(`Connected to port: ${port}`));*/

const server = new GraphQLServer({ typeDefs, resolvers })
mongoose.connection.once("open", function(){
    server.start(() => console.log('Server is running on localhost:4000'))
});

app.use('/graphql', graphqlHTTP({
    schema: typeDefs,
    rootValue: resolvers,
    graphiql: true,
  })
);
  

app.use('/api/register', register);
app.use('/api/login', login);
app.use('/api/contact_book', contact);
app.get('/', expressPlayground({ endpoint: '/graphql' }));

这是我在 GrapQL PLayground 上得到的错误截图 Error Screenshot

【问题讨论】:

    标签: node.js mongodb graphql


    【解决方案1】:

    您应该通过_id 而不是id 查找User 文档。而且您无需致电save,因为findOneAndUpdate 已经进行了更新。

    const user = await User.findOneAndUpdate(
      { _id: args.id },
      {
        name: args.name,
        password: args.password,
        email: args.email,
        phone: args.phone,
      },
      { new: true }
    )
    

    您也可以使用Model.findByIdAndUpdate 方法。

    const user = await User.findByIdAndUpdate(
      args.id,
      {
        name: args.name,
        password: args.password,
        email: args.email,
        phone: args.phone,
      },
      { new: true }
    )
    

    您应该对updateContact 执行相同的操作。还有几个问题。调用contact_book.findOneAndUpdate 时不应使用new 关键字。并且您应该将args.phone 传递给更新文档中的phone 键(您的代码传递args.email)。

    const resolvers = {
      // ...
      updateUser: (_, args) =>
        User.findOneAndUpdate(
          { _id: args.id },
          {
            name: args.name,
            password: args.password,
            email: args.email,
            phone: args.phone,
          },
          { new: true }
        ),
      updateContact: (_, args) =>
        contact_book.findOneAndUpdate(
          { _id: args.id },
          {
            name: args.name,
            email: args.email,
            phone: args.phone,
          },
          { new: true }
        ),
      // ...
    }
    

    【讨论】:

      猜你喜欢
      • 2018-02-28
      • 2021-11-08
      • 2020-02-06
      • 2018-06-15
      • 1970-01-01
      • 2020-10-24
      • 1970-01-01
      • 2020-01-16
      • 2020-05-05
      相关资源
      最近更新 更多