Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Graphql 如何编写变异解析器来更改对象的一个或多个特定值?_Graphql_Schema_React Apollo - Fatal编程技术网

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

Graphql 如何编写变异解析器来更改对象的一个或多个特定值?,graphql,schema,react-apollo,Graphql,Schema,React Apollo,期望一个解析器处理一个或多个对象值的任意组合的输入似乎是合理的。我不应该为“title”、“published”、“author”等单独编写解析器,对吗 下面是我的示例对象: let books = [ { title: 'Clean Code', published: 2008, author: 'Robert Martin', id: 'afa5b6f4-344d-11e9-a414-719c6709cf8e', genres: ['refacto

期望一个解析器处理一个或多个对象值的任意组合的输入似乎是合理的。我不应该为“title”、“published”、“author”等单独编写解析器,对吗

下面是我的示例对象:

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技能相当不稳定,我猜答案在于一个更雄辩的映射函数,但由于代码在graphql模式模块中运行,它无法处理
console.log
,因此故障排除是有问题的。任何解决这一问题的建议都会非常有用,这样我就能更好地解决自己的问题。

两点

无需使用地图或重新分配
书籍
。由于
book
变量是对books数组中对象的引用,因此您可以对其进行变异(但不能重新分配),并将变异数组中的对象。有关更多详细信息,请参阅

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.title
仅在
args.title
未定义
null
0
NaN
false
时使用

book.title = args.title || book.title
可以使用,它将属性从一个对象复制到另一个对象。由于
args
将丢失那些未提供的属性,因此您只需执行下面的代码片段。这更加优雅和简洁,但只有在参数名称与属性名称匹配时才起作用

Object.assign(book, args)
您可以在
args
对象中循环。如果您有一个或多个参数与
book
的属性不匹配,这可能更可取:

Object.keys(args).forEach(argName => {
  const argValue = args[argName]
  book[argName] = argValue
})
综合起来,我们可能会:

const book = books.find(b => b.id === args.id)
if (book) {
  Object.assign(book, args)
}
return book
几点

无需使用地图或重新分配
书籍
。由于
book
变量是对books数组中对象的引用,因此您可以对其进行变异(但不能重新分配),并将变异数组中的对象。有关更多详细信息,请参阅

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.title
仅在
args.title
未定义
null
0
NaN
false
时使用

book.title = args.title || book.title
可以使用,它将属性从一个对象复制到另一个对象。由于
args
将丢失那些未提供的属性,因此您只需执行下面的代码片段。这更加优雅和简洁,但只有在参数名称与属性名称匹配时才起作用

Object.assign(book, args)
您可以在
args
对象中循环。如果您有一个或多个参数与
book
的属性不匹配,这可能更可取:

Object.keys(args).forEach(argName => {
  const argValue = args[argName]
  book[argName] = argValue
})
综合起来,我们可能会:

const book = books.find(b => b.id === args.id)
if (book) {
  Object.assign(book, args)
}
return book

不完全确定“由于代码在graphql架构模块中运行,它不处理console.log”是什么意思——您可以在解析程序代码中调用
console.log
,它将写入标准输出。@DanielRearden我只是试图解释-诚然,我可能误解了一些东西-对的答案。我可能在如何使用VisualStudio代码方面遗漏了一些东西。我从来没有弄清楚如何在VSC中运行code repl风格,我承认我过于依赖
控制台.log
lol。但我刚才又试了一次-健全性检查-如果我运行前端应用程序并在chrome devtools中使用
检查
,我确实看到了
控制台.log
输出。但是仍然没有标准的输出。正如回答所说,您不能在服务器端记录一些东西,并期望它显示在您的客户端代码中。大概您是通过输入类似于
node server
npm start
的命令来运行服务器的。无论您在何处输入该命令,都将显示控制台输出。不完全确定您所说的“由于代码在graphql架构模块中运行,因此它不处理console.log”是什么意思--您可以在解析器代码中调用
console.log
,它将写入标准输出。@DanielRearden我只是试图解释-诚然,我可能误解了-的答案。我可能在如何使用VisualStudio代码方面遗漏了一些东西。我从来没有弄清楚如何在VSC中运行code repl风格,我承认我过于依赖
控制台.log
lol。但我刚才又试了一次-健全性检查-如果我运行前端应用程序并在chrome devtools中使用
检查
,我确实看到了
控制台.log
输出。但是仍然没有标准的输出。正如回答所说,您不能在服务器端记录一些东西,并期望它显示在您的客户端代码中。大概您是通过输入类似于
node server
npm start
的命令来运行服务器的。无论您在何处输入该命令,都将显示控制台输出。是!精彩的!其中两个选项非常有效,第一个和最后一个。我几乎不能相信
Object.assign
方法能按原样工作,它是如此简单和优雅!然而,仅仅因为我好奇,我想让
Object.keys
方法也能工作,这样我就能更好地理解它。我在我的代码中尝试了它,但我不知道在
[bookProperty]
中放什么。。。我的ARG确实总是很好