Apollo GraphQL解析器报错:Cannot read properties of undefined (reading 'liked')
问题:GraphQL查询过滤时出现
TypeError: Cannot read properties of undefined (reading 'liked') 在Sandbox中执行带过滤的GraphQL查询时,收到以下错误:
"TypeError: Cannot read properties of undefined (reading 'liked')",
" at Object.movies (.../server/schema/resolvers.js:14:45)"
我尝试修改类型定义和查询来测试其他属性,但错误依旧。相关代码如下:
相关代码
index.js
const { ApolloServer } = require("apollo-server"); const { typeDefs } = require("./schema/type-defs"); const { resolvers } = require("./schema/resolvers"); const server = new ApolloServer({ typeDefs, resolvers }); server.listen().then(({ url }) => { console.log(`YOUR API IS RUNNING AT: ${url} :)`); });
FakeData.js
const MovieList = [ { id: 1, name: "Avengers Endgame", year: 2019, liked: true, }, { id: 2, name: "Interstellar", year: 2007, liked: true, }, { id: 3, name: "Superbad", year: 2007, liked: true, }, { id: 4, name: "Madagascar 12", year: 2073, liked: false, }, ]; module.exports = { MovieList };
type-defs.js
const { gql } = require("apollo-server"); const typeDefs = gql` type Movie { id: ID! name: String! year: Int! liked: Boolean! } input MovieFilters { liked: Boolean! year: Int! } input MovieInput { filter: MovieFilters } type Query { movie(id: ID!): Movie movies(input: MovieInput): [Movie]! } `; module.exports = { typeDefs };
resolvers.js
const { MovieList } = require("../FakeData"); const _ = require("lodash"); const resolvers = { Query: { movies: (parent, args) => { const { filter } = args; const shouldApplyFilters = filter !== null; let movies = MovieList; if (!shouldApplyFilters) return movies; const shouldApplyLikedFilter = filter.liked !== null; const shouldApplyYearFilter = filter.year !== null; if (shouldApplyLikedFilter) { movies = movies .filter((a) => a.liked === filter.liked) } if (shouldApplyYearFilter) { movies = movies .filter((a) => a.year === filter.year) } return movies; }, } }; module.exports = { resolvers };
查询语句
query GetMoviesByFilter($input: MovieInput) { movies(input: $input) { id name liked year } }
查询变量
{ "input": { "filter": { "year": 2007, "liked": true } } }
问题原因与修复
核心错误
resolvers.js 中参数解构错误:你直接从 args 中解构 filter,但实际传入的参数是包裹在 input 对象里的,导致 filter 为 undefined,后续读取 filter.liked 就会报错。
修复后的代码
修复 resolvers.js
const { MovieList } = require("../FakeData"); const resolvers = { Query: { movies: (parent, args) => { // 正确从input中提取filter const { input } = args; const filter = input?.filter; let movies = [...MovieList]; // 拷贝原数组避免修改源数据 if (!filter) return movies; // 同时处理undefined和null的情况 if (filter.liked !== undefined && filter.liked !== null) { movies = movies.filter(a => a.liked === filter.liked); } if (filter.year !== undefined && filter.year !== null) { movies = movies.filter(a => a.year === filter.year); } return movies; }, } }; module.exports = { resolvers };
优化 type-defs.js(可选)
原 MovieFilters 中 liked 和 year 设为必填,实际场景中可能只需要单个过滤条件,建议改为可选:
const { gql } = require("apollo-server"); const typeDefs = gql` type Movie { id: ID! name: String! year: Int! liked: Boolean! } input MovieFilters { liked: Boolean year: Int } input MovieInput { filter: MovieFilters } type Query { movie(id: ID!): Movie movies(input: MovieInput): [Movie]! } `; module.exports = { typeDefs };
内容的提问来源于stack exchange,提问作者paq
相关产品推荐
相关产品推荐

