Search code examples
mongodbmongoosegraphqlgraphql-jsexpress-graphql

The graphiql mutation request succeeds but returns null


When I do a mutation on graphiql which is using my code for the GraphQL server, it returns null for all entries in the object.

I am using a Node and Express back end and it is using a MongoDB database that uses mongoose to access it.

updateTodo: {
  type: TodoType,
  args: {
    id: {
      type: new GraphQLNonNull(GraphQLID)
    },
    action: {
      type: new GraphQLNonNull(GraphQLString)
    }
  },
  resolve(parent, args) {
    return Todo.updateOne({ // updateOne is a MongoDB/mongoose function
      _id: args.id
    }, {
      $set: {
        action: args.action
      }
    });
  }
}

What I get

{
  "data": {
    "updateTodo": {
      "id": null,
      "action": null
    }
  }
}

from the following

mutation {
  updateTodo(id: "5c18590fa6cd6b3353e66b06", action: "A new Todo") {
    id
    action
}

I do this afterwards

{
  todos{
    id
    action
  }
}

and I get this

{
  "data": {
    "todos": [
      {
        "id": "5c18590fa6cd6b3353e66b06",
        "action": "A new Todo"
      }
    ]
  }
}

so I know it is working but would prefer to get the new data return.

More info

const TodoType = new GraphQLObjectType({
  name: 'Todo',
  fields: () => ({
    id: {
      type: GraphQLID
    },
    action: {
      type: GraphQLString
    },
    isCompleted: {
      type: GraphQLBoolean
    },
    user: {
      type: UserType,
      resolve(parent, args) {
        return User.findById(parent.userId);
      }
    }
  })
});

Imported into the file.

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const todoSchema = new Schema({
  action: String,
  isCompleted: Boolean,
  userId: String
})

module.exports = mongoose.model('Todo', todoSchema);

Here is the github repository so you can look at the code https://github.com/petersrule/graphql-node-express-boilerplate


Solution

  • Please try to use the below updated code in your resolver function for update, "{new: true}" helps to return the updated object from mongoDB. i hope this will help.

    updateTodo: {
      type: TodoType,
       args: {
         id: {
          type: new GraphQLNonNull(GraphQLID)
         },
         action: {
          type: new GraphQLNonNull(GraphQLString)
         }
       },
     resolve(parent, args) {
        return new Promise((resolve, reject) => {
            Todo.findOneAndUpdate({ // updateOne is a MongoDB/mongoose function
                "_id": args.id
              }, {
                $set: {
                  "action": args.action
                }
              }, {
                new: true // This makes sure the return result is the updated information
              })
              .then((result) => {
                return resolve(result);
              })
              .catch((err) => {
                return reject(err);
              })
          })
          .then((finalResult) => {
            return finalResult;
          })
          .catch((err) => {
            return err;
          })
      }
    }
    

    Please do let me know the result.