如何编写突变解析器以更改对象的一个 或多个特定值?

问题描述 投票:1回答:1

期待一个解析器处理一个或多个对象值的任意组合的输入似乎是合理的。我不必为“标题”,“已发布”,“作者”等编写单独的解析器,对吗?

这是我的示例对象:

let books = [
  {
    title: 'Clean Code',
    published: 2008,
    author: 'Robert Martin',
    id: 'afa5b6f4-344d-11e9-a414-719c6709cf8e',
    genres: ['refactoring'],
  },
  {
    title: 'Agile software development',
    published: 2002,
    author: 'Robert Martin',
    id: 'afa5b6f5-344d-11e9-a414-719c6709cf9e',
    genres: ['agile', 'patterns', 'design'],
  },
]

typeDefs:

const typeDefs = gql`
  type Book {
    title: String
    published: Int
    author: String
    id: ID
    genres: [String]
  }

  type Query {
    bookCount: Int!
    allBooks(title: String, author: String, genre: String): [Book]
    findBooks(title: String!): Book
  }

  type Mutation {
    addBook(
      title: String!
      published: Int
      author: String!
      genres: [String]
    ): Book
    editBook(
      id: ID
      title: String
      published: Int
      author: String
      genres: [String]
    ): Book
  }
`

这里是我目前拥有的解析器:

 Mutation: {
     editBook: (_, args) => {
      const book = books.find(b => b.id === args.id)
      if (!book) {
        return null
      }
      const updatedBook = {
        ...book,
        title: args.title,
        author: args.author,
        published: args.published,
        genres: [args.genres],
      }
      books = books.map(b => (
        b.id === args.id ? updatedBook : b))
      return updatedBook
    },
    }

这是当前正在发生的事情。

原始对象:

"allBooks": [
      {
        "id": "afa5b6f4-344d-11e9-a414-719c6709cf8e",
        "title": "Clean Code",
        "author": "Robert Martin",
        "published": 2008,
        "genres": [
          "refactoring"
        ]
      },
{...}
]

突变查询:

mutation {
  editBook(id:"afa5b6f4-344d-11e9-a414-719c6709cf8e", title:"changed"){
    id
    title
    author
    published
    genres
  }
}

返回此:

{
  "data": {
    "editBook": {
      "id": "afa5b6f4-344d-11e9-a414-719c6709cf8e",
      "title": "changed",
      "author": null,
      "published": null,
      "genres": [
        null
      ]
    }
  }
}

我如何编写解析器来更改一个或多个对象的值,而不将未指定的值更改为'null'?

我承认,我的JavaScript技能相当不稳定,我猜测答案在于更加雄辩的map函数,但是由于代码在graphql模式模块中运行,因此无法处理console.log,因此故障排除是有问题的。任何解决的建议也将非常有帮助,因此我可以更好地解决自己的问题。

graphql schema react-apollo
1个回答
0
投票

点对点

无需使用地图或重新分配books。因为book变量是对books数组中的对象的引用,所以可以对其进行突变(但不能重新分配),并且可以对数组中的对象进行突变。有关更多详细信息,请参见this question

const book = books.find(b => b.id === args.id)
if (book) {
  // you cannot reassign book and still have the original value change,
  // but you can mutate it
  book.title = args.title
  book.author = args.author
  book.published = args.published
  book.genres = args.genres
}
return book

要仅更改args中存在的值,您可以使用一些选项:

如果第一个值为false,则可以使用逻辑OR运算符(||)提供另一个值进行分配。在此,仅当book.titleargs.titleundefinednull0NaN""时才使用false

book.title = args.title || book.title

您可以使用Object.assign,它将属性从一个对象复制到另一个对象。由于args将缺少那些未提供的属性,因此您可以执行以下代码片段。这更加简洁明了,但仅在参数名称与属性名称匹配时才有效。

Object.assign(book, args)

您可以遍历args对象。如果您有一个或多个与book的属性不匹配的参数,则可能更需要这样做:

Object.keys(args).forEach(argName => {
  const argValue = args[argName]
  book[bookProperty] = argValue
})

将它们放在一起,我们可能会做:

const book = books.find(b => b.id === args.id)
if (book) {
  Object.assign(book, args)
}
return book
© www.soinside.com 2019 - 2024. All rights reserved.