微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

GraphQL/Apollo 服务器:无法访问嵌套对象

如何解决GraphQL/Apollo 服务器:无法访问嵌套对象

问题:尝试查询用户购物车中的产品时出现以下错误

“ID 不能代表值:

我的查询

query getBasket{
  getBasket {
    id
    quantity
    createdAt
    product{
      id         <--- produces error
      title      <--- removing ID,product.title becomes null
      stock      <--- becomes null if ID is removed from query
    }
  }
}

如果我省略产品字段,一切都会按预期工作,但我需要能够显示用户购物车的产品信息。当我尝试检索产品信息时出现错误

我的 GraphQL 定义如下(我是新手),User 和 Item(代表篮子中的物品)之间应该存在一对多的关系:

module.exports = gql(`

    enum Role {
      ADMIN
      USER
    }
    
    type Item {
      id: ID!
      product: Product!
      quantity: Int!
      createdAt: String!
    }

    type User  {
      id: ID!
      email: String!
      token: String!
      roles: [Role]!
      basket: [Item]!
      createdAt: String!
    } 
    
    type Product {
      id: ID!
      title: String!
      description: String!
      stock: Boolean
      price: String
    }

    input RegisterInput {
      email: String!
      password: String!
      confirmPassword: String!
    }

    type Query {
      getProducts: [Product]
      getProduct(productId: ID!): Product
      getBasket: [Item]
      getUsers: [User]
    }

    type Mutation {
      register(registerInput: RegisterInput): User!
      login(email: String!,password: String!): User!
      createProduct(title: String!,description: String,stock: Boolean,price: String!): Product!
      deleteProduct(productId: ID!): String!    
      addToBasket(productId: String!,quantity: String!): User!
      deleteFromBasket(productId: String!): User!
    }
`);

我可以将产品添加到购物篮中,只是当我尝试检索用户的购物篮时出现错误

单击此处查看我的数据在 MongoDB 图集上的样子:https://i.stack.imgur.com/RKcnP.png

关于我尝试将字符串 ID 转换为对象 ID 的错误的帖子只有几篇。这可能是 GraphQL 的问题?我不确定,也许我需要重做我的 GraphQL 定义。

用户架构:

const userSchema = new Schema({
    email: String,password: String,roles: [String],basket: [
        {
            product: {
                type: Schema.Types.ObjectId,ref: 'products'
            },quantity: String,createdAt: String
        }
    ],createdAt: String
});

AddToBasket 突变:

Mutation: {
        addToBasket: async (_,{productId,quantity},context) => {
            // Todo: Validate input fields
            console.log("adding to basket")
            const userContext = checkAuth(context,USER);
            const user = await User.findById(userContext.id);
            const product = await Product.findById(productId);
            if (product) {
                user.basket.unshift({           //this adds the following into the basket as an object 
                    product: product.id,quantity,createdAt: new Date().toISOString()
                });
                await user.save();
                return user;
            } else throw new UserInputError('Product not found');
        }
    }

感谢您的帮助!

编辑 11:51 06/03/2021:(已删除

编辑 2 12:25 06/03/2021:

GraphQLError: ID cannot represent value: <Buffer...>"

我的问题与此人的问题完全相同,但我认为他们的代码与我的不同?我如何返回用户的购物篮如下:

Query: {
        getBasket: async (_,{},context) => {
            console.log("RUNNING");
            const userContext = checkAuth(context,USER);
            const user = await User.findById(userContext.id);
            return user.basket;
        }
    },

编辑 3 12:52 06/03/2021:

这是我的用户架构:

const { model,Schema } = require('mongoose');

const userSchema = new Schema({
    email: String,createdAt: String
});

module.exports = model('User',userSchema);

解决方法

  1. 我的架构引用是错误的,我在阅读了这篇文章的一个答案后发现了这一点:MissingSchemaError: Schema hasn't been registered for model "User"
 basket: [
        {
            product: {
                type: Schema.Types.ObjectId,ref: 'products' <--- changed to 'Product' (the name of my 'Product'Schema)
            },quantity: String,createdAt: String
        }
    ],
  1. 我发现我的嵌套对象没有被填充,所以我阅读了这个以更好地理解: https://dev.to/paras594/how-to-use-populate-in-mongoose-node-js-mo0 。我在返回 user.basket 之前通过 console.logging user.basket 值(和其他字段)发现了这一点,我发现 user.basket 未定义。

  2. 我将我的 getBasket 查询重新编写为以下内容,在这里我确保我正在填充篮子字段内的篮子字段和产品字段。

如果没有 .populate,错误“ID 不能代表值:

Query: {
        getBasket: async (_,{},context) => {
            console.log("RUNNING");
            const userContext = checkAuth(context,USER);
            const user = await User.findById(userContext.id,{basket:1})    
            .populate({
                path: "basket",// populate basket
                populate: {
                   path: "product",// in basket,populate products
                   select: {title:1,stock:1,price:1}
                }
            })
            .exec();
            return user.basket;
        }
    },

如果您的查询结果为空,请阅读此答案以更好地理解:Why does a GraphQL query return null?

答案 = 填充嵌套字段

请随时发布可能进行的任何改进或更改。

感谢以斯拉帮助我!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。