简体   繁体   中英

GraphQL and Mongoose overwrite property to null with not passed argument in mutation

I've tried to simplify example as possible so if any additional information needed I could provide it. Let's say we have easy Schema with embed GraphQLObjectType:

const nameType = new GraphQLObjectType({
  name: 'NameType',
  fields: {
    first: new GraphQLNonNull(GraphQLString),
    last: GraphQLString,
  },
});

const userType = new GraphQLObjectType({
  name: 'User',
  fields: () => ({
    id: new GraphQLNonNull(GraphQLID),
    name: new GraphQLNonNull(nameType),
    email: new GraphQLNonNull(GraphQLString),
  }),
});

So I have name with properties first and last here. For updating I've written mutation as below. There is GraphQLInputObjectType represent as NameType.

const nameType = new GraphQLInputObjectType({
  name: 'NameInput',
  fields: {
    first: new GraphQLNonNull(GraphQLString),
    last: GraphQLString,
  },
});

const updateUser = {
  name: 'UpdateUser',
  type: userType,
  args: {
    id: new GraphQLNonNull(GraphQLID),
    name: nameType,
    email: GraphQLString,
  },
  resolve: (_, args, context) => User.findOneAndUpdate({ _id: args.id }, args, { new: true })
};

So when I'm passing any mutation with name: {first: "Foo"} property last always get overrides with null value. I'm forced to pass previous first name and new last name if I need to change last name. I would like to have a possibility to update only one first or last without affect another. How I can reach it out?

That's because Mongoose update property modify nested objects as a whole. So if we need to deep merge within update operation, we need something as here .

If we need to cover more nested layers we can use this code in while loop.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM