Sotiris Kourouklis
Sotiris Kourouklis

Reputation: 33

Graphql mongodb cannot return _id

Hi everyone I am creating an api with graphql and mongodb. I am using mongodb aggregation to filter my documents.

export const findAllVariants = async (_, { orderby, filter, skip, sort, perPage }, context) => {
  await jwtAuthentication.verifyTokenMiddleware(context);

  try {
    const aggregate = Variant.aggregate();
    const match = { $and: [] };

    if (filter) {
      await filter.split(' ').forEach((f) => {
        match.$and.push({
          $or: [
            {
              color: {
                $regex: new RegExp(transliterate(f), 'i')
              }
            },
            {
              size: {
                $regex: new RegExp(transliterate(f), 'i')
              }
            },
            {
              sku: {
                $regex: new RegExp(transliterate(f), 'i')
              }
            },
            {
              barcode: {
                $regex: new RegExp(transliterate(f), 'i')
              }
            }
          ]
        });
      });
      aggregate.match(match);
    }

    const options = {
      allowDiskUse: true,
      limit: perPage,
      page: skip,
      sortBy: { [orderby]: sort }
    };

    return Variant.aggregatePaginate(aggregate, options, (err, results, pageCount, count) => {
      if (err) {
        return new ApolloError(`There was an error ${err}`);
      }
      console.log(results);
      return {
        count,
        variants: results,
        pageCount,
        skip
      };
    });
  } catch (err) {
    return new ApolloError(`There was an error ${err}`);
  }
};

My graphql def is this

export default gql`
  type VariantsResult {
    variants: [Variant]
    count: Int
    pageCount: Int
    skip: Int
  }

  type Variant {
    id: String!
    color: String
    size: String
    quantity: Int
    sku: String
    barcode: String
    price: Price
    images: [String]
  }

  input VariantInfo {
    id: ID!
    color: String!
    size: String!
    quantity: Int
    sku: String!
    barcode: String!
    price: InputPrice!
    images: [ImageInfo]!
  }

  extend type Query {
    findAllVariants(orderby: Int, filter: String, skip: Int, sort: Int, perPage: Int): VariantsResult
  }

  extend type Mutation {
    createVariant(variantInfo: VariantInfo): Variant!
    removeVariantFromProduct(variantInfo: VariantInfo, productInfo: ProductInfo): Product!
    addVariantToProduct(variantInfo: VariantInfo, productInfo: ProductInfo): Product!
    editVariantFromProduct(variantInfo: VariantInfo): Variant!
  }
`;

Now in apollo playground when i provide the data needed and I return the id value it says the following message "Cannot return null for non-nullable field Variant.id."

This only happens for the id field, all the others work just fine. Please help!

Upvotes: 0

Views: 1234

Answers (1)

Ezra Siton
Ezra Siton

Reputation: 7741

The error:

ID! means that the field is non-nullable (https://graphql.org/learn/schema/):

id: ID!

In your case Variant.id is null (Throw error).

Using nullability in GraphQL : https://www.apollographql.com/blog/using-nullability-in-graphql-2254f84c4ed7/

Possible solution:

Mongodb use _id not id

enter image description here

the type could be:

type Player{
  _id: String
  name: String
  salary: String
}

Get data by id could look like this (ObjectID docs):

db.collection('baseballPlayers').findOne({ _id: ObjectID("5faeda2c7e348a5e142827ae") });

Or on compass:

enter image description here

Sum: Start from simple Query by id (Before you getting inside aggregations) and check if the return value is null (or not). Then use the correct query inside _id feild resolver.

Related Q:

Related tutorial:

Upvotes: 1

Related Questions