node.js - Node - GraphQL - Ad.user 字段类型必须是输出类型,但得到 : undefined

标签 node.js output undefined graphql circular-dependency

我在 AdType 中使用 UserType 时似乎遇到了循环依赖问题。

这是我的用户类型文件:UserType

这是我的 AdType 文件:AdType

如果我尝试使用下面的代码,即使我正确导入了 UserType,也会收到错误“Ad.user 字段类型必须是输出类型,但得到:未定义”。

import { UserType } from '../User/user.graphql.model'
import { UserSchema } from '../User/user.mongoose.model'

const user =  {
  type: UserType,
  resolve(parentValue, args) {
    return UserSchema.findById(parentValue.user);
  }
};

//------------------------------
// Ad Type
//------------------------------
export const AdType = new GraphQLObjectType({
  name: 'Ad',
  fields: () => ({
    id,
    user,
    title,
    views,
    availability,
... more code

如果我在导入 AdType 后尝试在 AdType 中控制台记录 UserType,它会显示未定义,但当我将其用作:

//------------------------------
// Ad Type
//------------------------------
export const AdType = new GraphQLObjectType({
  name: 'Ad',
  fields: () => ({
    id,
    user: {
      type: UserType,
      resolve(parentValue, args) {
        return UserSchema.findById(parentValue.user);
      }
    },
    title,
... more code

它按预期工作,只是不允许我提取代码来分隔常量。 我以相同方式导入和使用的所有其他类型都按预期工作,将广告导入用户也可以,但将用户导入广告似乎会中断。两者的代码基本上相同,只是信息不同。

最佳答案

I am already using fields: () => ( { } ) to lazily load fields to avoid problems with circular dependencies, so this problem is really banging against my head.

但是你做得不对。 JavaScript 没有惰性求值。这意味着 user 的值不是在调用函数时确定的,而是在对 const 变量定义求值时确定的。此时,变量UserType 没有任何值,因此未定义。您的对象定义需要在调用函数时进行。如果仍然不清楚,我可以详细说明您的类型是如何解析的。

尝试内联定义用户类型或将其设为函数:

const user = () => ({ type: UserType, /* ... */ })

export const AdType = new GraphQLObjectType({
  name: 'Ad',
  fields: () => ({
    id,
    user: user(),
    title,
    views,
    availability,

我不确定为什么你将字段放入单独的常量中,你的代码看起来并没有那么大,它提高了可读性,但当然我可能是错的。

好吧,让我们看看模块是如何解析的。为了使这更容易,我使用 CJS,因为你很可能无论如何都会将代码转译下来,而 ES 模块只是慢慢地进入 Node 。

// user.graphql.model.js
const adModule = require('ad.graphql.model.js');

// Node tries to resolve ad.graphql.model.js
const userModule = require('user.graphql.model.js');
// Ups, this one has been resolved already and required this as dependency.
// We have no other choice than to assign an empty object here
// userModule is {}
const user =  {
  type: userModule.UserType, // undefined
  resolve(parentValue, args) {
    return UserSchema.findById(parentValue.user);
  }
};
// finish this module and return to user.graphql.model.js
// adModule now contains the resolved module
const adModule = require('ad.graphql.model.js');
// finish module and replace {} with actual module content in ad.graphql.model.js
// userModule contains UserType
const userModule = require('user.graphql.model.js');

const ads = {
  type: new GraphQLList(asModule.AdType), // GraphQLObjectType
}

// Now your Schema does build/inits itself after the config has been specified
// (and all modules have been resolved)
// imagine user being a function now taht is called on Schema init
const user = () => ({
  type: userModule.UserType, // GraphQLObjectType
  /* ... */
})

关于node.js - Node - GraphQL - Ad.user 字段类型必须是输出类型,但得到 : undefined,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48286657/

相关文章:

javascript - "restClient is not defined"虽然它实际上是

javascript - JQuery 在 Jest 测试中检查元素可见性

javascript - React Native 上的 git clone 错误如何解决这个问题

java - 如何去掉输出末尾的空格?

java - 发送电子邮件时如何在控制台上禁用 java 邮件跟踪

perl - 什么时候可以在启用警告的情况下在 perl 中使用 undefined variable ?

javascript - Fullcalendar dayRender 未定义单元格属性

node.js - Kue 是否使用 Redis 订阅任何 (*) 模式?

visual-studio - 如何防止VS中的Output窗口消失?

php - 错误 : undefined index?