0

这是我的打字稿对象(简化):

@ObjectType()
export default class Game {
  @Field(() => ID)
  id?: string

  @arrayProp({items: Player})
  @Field(() => [Player])
  players: Player[] = []
}

@ObjectType()
export class Player {
  @Field(() => ID)
  id?: string
}

它使用 type-graphql 生成此模式:

type Game {
  id: ID!
  players: [Player!]!
}
type Player {
  id: ID!
}

我使用解析器来查询用户的游戏:

@Resolver(() => User)
export class UserGameResolver {
  @FieldResolver(() => [Game])
  async ongoingGames(@Ctx('userId') userId: string) {
    return GameModel.find({'players.userId': userId, setup: null})
  }
}

它会产生此错误:“GraphQL 错误:无法为不可为空的字段 Player.id 返回 null”

我已经知道的:

  • 游戏和玩家“id”字段是由 Mongoose 创建的“虚拟”字段,作为真实属性“_id”的别名(我不想在前端操作 _id,我想序列化别名)。
  • 如果我不查询游戏的玩家,它会起作用。所以 Game.id 由我的 apollo 服务器解析器正确序列化。所以对于这个对象,虚拟属性被正确地访问和序列化。
  • 玩家 ID 存在并且虚拟属性在猫鼬方面有效:如果我执行 console.log(mongooseResult[0].players[0].id),我可以在控制台中看到我的玩家 ID。
  • 假设 Apollo 服务器对 player.id 使用此默认字段解析器: https ://github.com/graphql/graphql-js/blob/master/src/execution/execute.js#L1181-L1199 (文档:https:// /www.apollographql.com/docs/apollo-server/data/resolvers/#default-resolvers)。根据源代码,虚拟属性应该被序列化,因为它是这样访问的:'player['id']'。

如果有人知道这里发生了什么,那就太好了!

4

1 回答 1

1

你应该尝试使用_id

如果您真的想使用id(虚拟),那么您需要使用.toJson.toObject使用选项{ virtuals: true }

return GameModel.find({'players.userId': userId, setup: null}).toObject({ virtuals: true });
于 2020-04-18T09:59:38.700 回答