节点 - GraphQL - Ad.user 字段类型必须是输出类型但得到:未定义 [英] Node - GraphQL - Ad.user field type must be Output Type but got: undefined

查看:15
本文介绍了节点 - GraphQL - Ad.user 字段类型必须是输出类型但得到:未定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I seem to be having circular dependency problems with using UserType inside AdType.

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

This is my UserType file: UserType

这是我的 AdType 文件:广告类型

This is my AdType file: AdType

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

If I try to use the code below I get the error "Ad.user field type must be Output Type but got: undefined" even tho I imported the UserType properly.

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 中控制台日志 UserType,它会显示未定义,但是当我将其用作:

If I try to console log UserType inside AdType after importing it, it says undefined, but when I use it as:

//------------------------------
// 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

它按预期工作,只是不允许我拉出代码来分隔常量.我以相同方式导入和使用的所有其他类型都按预期工作,将 Ads 导入 Users 也可以工作,但将 User 导入 Ads 似乎中断了.两者的代码基本相同,只是信息不同.

it works as intended, it just doesn't allow me to pull out the code to separate constant. All other Types I import and use in the same manner work as expected, importing Ads into Users works as well, but importing User into Ads seems to break. It's basically the same code in both, just different info.

推荐答案

我已经在使用 fields: () => ( { } ) 来延迟加载字段以避免循环依赖问题,所以这个问题真的让我很头疼.

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 没有值,因此是未定义的.您的对象定义需要在调用函数时发生.如果仍然不清楚,我可以提供详细说明您的类型是如何解决的.

But you are not doing it correctly. Javascript does not have lazy evaluation. This means that the value of user is not determined when the function is called but at the point in time when the const variable definition is evaluated. At this point the variable UserType holds no value and thus is undefined. Your object definition needs to happen when the function is called. If it is still not clear I can offer to go into detail how your types are resolved.

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

Try defining the user type inline or make it a function:

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

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

我不知道你为什么把你的字段放到单独的常量中,你的代码看起来没有那么大,它提高了可读性,但当然我可能是错的.

I am not sure why you pull your fields into seperate constants, your code does not seem that big that it improves readability but of course I can be wrong.

好的,让我们看看模块是如何解决的.为使这更容易,我使用 CJS,因为您很可能无论如何都将代码转译下来,而 ES 模块只是慢慢地进入节点.

Okay, let's see how modules are resolved. To make this easier I use CJS because you most likely transpile the code down anyways and ES modules are just slowly coming to 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
  /* ... */
})

这篇关于节点 - GraphQL - Ad.user 字段类型必须是输出类型但得到:未定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆