简体   繁体   English

中继项目中的更新突变问题

[英]Problem with update mutation in Relay project

I am working on a Relay project and there is a problem with the update mutation.我正在做一个Relay项目,更新突变存在问题。 I'm new to Relay, and it's hard for me to establish what the problem is related to - with promises or with Relay settings.我是 Relay 的新手,我很难确定问题与什么有关 - 与承诺或Relay设置有关。 When sending a mutation, the findOneAndUpdate function does not save the data received from args.发送突变时, findOneAndUpdate function 不会保存从 args 接收到的数据。 I checked using console.log(args) that the data is coming into updateHero function.我使用console.log(args)检查了数据是否进入updateHero function。 I will give the files of my project.我将提供我的项目文件。 I would be grateful for any help.如果有任何帮助,我将不胜感激。 Thanks for attention.感谢关注。

hero.js: hero.js:

const mongoose = require('mongoose');
mongoose.set('useFindAndModify', false);

const Schema = mongoose.Schema;

const heroSchema = new Schema({
  name: {
    type: String,
    required: true
  },
  description: {
    type: String,
    required: true
  },
  img: {
    type: String,
    required: true
  },
  date: {
    type: Date,
    required: true
  }
});

var heroModel = mongoose.model("Hero", heroSchema);

module.exports = {
  getHeroes: () => {
    return heroModel.find().sort({ _id: -1 })
      .then(heroes => {
        return heroes.map(hero => {
          return {
            ...hero._doc,
            id: hero.id,
            date: new Date(hero.date).toISOString()
          };
        });
      })
      .catch(err => {
        throw err;
      });
  },
  getHero: id => {
    return heroModel.findOne({ _id: id });
  },
  createHero: hero => {
    return heroModel(hero).save();
  },
  removeHero: id => {
    return heroModel.findByIdAndRemove(id);
  },
  updateHero: (args) => {
    return new Promise((resolve) => {
      (async () => {
        await heroModel.findOneAndUpdate(
          { id: args.id },
          {
            name: args.name,
            description: args.description,
            img: args.img,
            date: args.date
          },
          { new: true }
        );
      })();
      resolve("OK");
    });
  }
};

mutation.js:突变.js:

const {
  GraphQLObjectType,
  GraphQLNonNull,
  GraphQLString,
  GraphQLBoolean
} = require('graphql');

const { fromGlobalId, mutationWithClientMutationId } = require('graphql-relay');
const { Hero } = require('./types/hero');

const heroModel = require('./models/hero');

const CreateHeroMutation = mutationWithClientMutationId({
  name: "CreateHero",
  inputFields: {
    name: { type: new GraphQLNonNull(GraphQLString) },
    description: { type: new GraphQLNonNull(GraphQLString) },
    img: { type: new GraphQLNonNull(GraphQLString) },
    date: { type: new GraphQLNonNull(GraphQLString) }
  },
  outputFields: {
    hero: {
      type: Hero
    }
  },
  mutateAndGetPayload: args => {
    return new Promise((resolve, reject) => {
      heroModel.createHero({
        name: args.name,
        description: args.description,
        img: args.img,
        date: new Date(args.date)
      })
        .then(hero => resolve({ hero }))
        .catch(reject);
    });
  }
});

const UpdateHeroMutation = mutationWithClientMutationId({
  name: "UpdateHero",
  inputFields: {
    id: { type: new GraphQLNonNull(GraphQLString) },
    name: { type: new GraphQLNonNull(GraphQLString) },
    description: { type: new GraphQLNonNull(GraphQLString) },
    img: { type: new GraphQLNonNull(GraphQLString) },
    date: { type: new GraphQLNonNull(GraphQLString) }
  },
  outputFields: {
    hero: {
      type: Hero
    }
  },
  mutateAndGetPayload: async args => {
    return new Promise((resolve, reject) => {
      heroModel.updateHero(args)
        .then(hero => resolve({ hero }))
        .catch(reject);
    });
  }
});

const RemoveHeroMutation = mutationWithClientMutationId({
  name: "RemoveHero",
  inputFields: {
    id: { type: new GraphQLNonNull(GraphQLString) },
  },
  outputFields: {
    deleted: { type: GraphQLBoolean },
    deletedId: { type: GraphQLString }
  },
  mutateAndGetPayload: async ({ id }, { viewer }) => {
    const { id: productId } = fromGlobalId(id);
    const result = await heroModel.removeHero(productId);
    return { deletedId: id, deleted: true };
  }
});

const Mutation = new GraphQLObjectType({
  name: "Mutation",
  description: "kjhkjhkjhkjh",
  fields: {
    createHero: CreateHeroMutation,
    removeHero: RemoveHeroMutation,
    updateHero: UpdateHeroMutation
  }
});

module.exports = Mutation;

Perhaps these files will be needed.也许需要这些文件。 nodes.js:节点.js:

const { nodeDefinitions, fromGlobalId } = require('graphql-relay');
const heroModel = require('./models/hero');

const { nodeInterface, nodeField } = nodeDefinitions(
  (globalId) => {
    const { type, id } = fromGlobalId(globalId);
    if (type == "Hero") {
      return heroModel.getHero(id);
    } else {
      return null;
    }
  },
  (obj) => {
    const { Hero } = require('./types/hero');
    if (obj instanceof Hero) {
      return Hero;
    }
    return null;
  }
);

module.exports = { nodeInterface, nodeField };

hero.js (type): hero.js(类型):

const {
  GraphQLObjectType,
  GraphQLString
} = require('graphql');

const { globalIdField, connectionDefinitions } = require('graphql-relay');
const { nodeInterface } = require('../nodes');

const Hero = new GraphQLObjectType({
  name: "Hero",
  description: "lkjlkjlkjlkjlk",
  interfaces: [nodeInterface],
  fields: () => ({
    id: globalIdField(),
    name: {
      type: GraphQLString,
      description: "The name of the hero"
    },
    description: {
      type: GraphQLString,
      description: "Hero biography"
    },
    img: {
      type: GraphQLString,
      description: "Portrait of hero"
    },
    date: {
      type: GraphQLString,
      description: "Date of birth"
    }
  })
});

const { connectionType: HeroConnection } = connectionDefinitions({
  nodeType: Hero
});

module.exports = { Hero, HeroConnection };

Relay server requires fromGlobalID method to pass id as an argument to mongoose schema.中继服务器需要 fromGlobalID 方法将 id 作为参数传递给 mongoose 模式。 The solution is to pass the "global id" and input arguments:解决方法是传递“全局 id”并输入 arguments:

const UpdateHeroMutation = mutationWithClientMutationId({
  name: "UpdateHero",
  inputFields: {
    id: { type: new GraphQLNonNull(GraphQLString) },
    name: { type: new GraphQLNonNull(GraphQLString) },
    description: { type: new GraphQLNonNull(GraphQLString) },
    img: { type: new GraphQLNonNull(GraphQLString) },
    date: { type: new GraphQLNonNull(GraphQLString) }
  },
  outputFields: {
    updated: { type: GraphQLBoolean },
    updatedId: { type: GraphQLString }
  },
  mutateAndGetPayload: async (args) => {
    const { id: productId } = fromGlobalId(args.id);
    const result = await heroModel.updateHero(productId, args);
    return { updatedId: args.id, updated: true };
  }
});

updateHero function from schema: updateHero function 从架构:

updateHero: (id, args) => {
    return heroModel.findByIdAndUpdate(
      id,
      {
        name: args.name,
        description: args.description,
        img: args.img,
        date: args.date
      },
      { new: true }
    );
  }

So it goes.就这样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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