0

Problem: Trying to query for products in user's basket breaks with the following error:

"ID cannot represent value: <Buffer 60 41 24 0c ae a8 b6 35 ac 33 5a cd>"

my query:

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

If I omit the product field, everything works as expected but I need to be able to display the product information for the user's basket. When I try retrieve the product information I get the error.

My GraphQL definitions are the following (I am new to this), there should be a one to many relationship between User and Item (which represents the items in their basket):

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!
    }
`);

I am able to add products into the basket, it's just when I try to retrieve the user's basket I get the error.

Click this to see how my data looks like on MongoDB atlas: https://i.stack.imgur.com/RKcnP.png

There's only a couple of posts about the error I tried converting the string ID to object ID. It could be a problem with GraphQL? I'm unsure, perhaps I need to redo my GraphQL Definitions.

User Schema:

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:

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');
        }
    }

Thank you for helping!

Edit 11:51 06/03/2021: (removed)

Edit 2 12:25 06/03/2021:

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

My problem is the exact same problem as this persons but I think their code is different to mine? How I return the user's basket is by the following:

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

Edit 3 12:52 06/03/2021:

Here is my user Schema:

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

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

module.exports = model('User', userSchema);
nk711
  • 1
  • 2

1 Answers1

0
  1. my schema references were wrong, I figured that out after reading one of the answers for this post: 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. I figured out that my nested objects weren't populated, so I read this for better understanding: https://dev.to/paras594/how-to-use-populate-in-mongoose-node-js-mo0 . I figured this out by console.logging the user.basket value (and other fields) before returning user.basket, I found that the user.basket was undefined.

  2. I redid my getBasket Query to the following, here I'm ensuring I'm populating the basket field and the product field inside the basket field.

Without .populate, the error "ID cannot represent value: <Buffer..." would prop up again.

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;
        }
    },

If your query result is null, then read this answer for better understanding: Why does a GraphQL query return null?.

ANSWER = POPULATE THE NESTED FIELD

Feel free to post any improvements or changes that could be made.

Thank you Ezra for helping me!

nk711
  • 1
  • 2