Graphql 如何编写变异解析器来更改对象的一个或多个特定值?
期望一个解析器处理一个或多个对象值的任意组合的输入似乎是合理的。我不应该为“title”、“published”、“author”等单独编写解析器,对吗 下面是我的示例对象: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
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确实总是很好