Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handling ObjectId in filter #57

Open
sscots opened this issue Jan 23, 2020 · 4 comments
Open

Handling ObjectId in filter #57

sscots opened this issue Jan 23, 2020 · 4 comments

Comments

@sscots
Copy link

sscots commented Jan 23, 2020

Say I want to get a specific person record and filter by _id

person (
   filter: {
       _id: { EQ: "5e1e2d653a32a05f51f621c1" }
   }
) {
   name { 
      lastName
   }
   age
}

Currently that will generate a filter like so

{ _id: { '$eq': '5e1e2d653a32a05f51f621c1' }

Can you detect when "_id" is used and make it essentially do this instead?

{ _id: { '$eq': new ObjectId('5e1e2d653a32a05f51f621c1') }
@yoavkarako
Copy link
Collaborator

Sorry for the overdue response.

That sounds like a feature worth adding to the package. I'm not sure when I'll get around to it, but in the meantime you can:

  • Add a PR
  • Since querying by _id about makes every other filter obsolete you can create a field like:
    id: {
        type: PersonType,
        args: { _id: { type: new GraphQLNonNull(GraphQLString) } },
        resolve: async (obj, args, { db }: { db: Db }, info) => {
            const projection = getMongoDbProjection(info, PersonType);
            return await db.collection('people').find({ _id: new ObjectId(args._id) }, { projection }).toArray();
        }
    }
    

@code-is-art
Copy link

code-is-art commented May 23, 2020

As long as your scalar type is ObjectId and not string it works just fine. same with date BTW.

or make your own...
ObjectId

import { GraphQLScalarType, Kind } from "graphql";
import { ObjectId } from "mongodb";

export const ObjectIdScalar = new GraphQLScalarType({
  name: "ObjectId",
  description: "Mongo object id scalar type",
  parseValue(value: string) {
    return new ObjectId(value); // value from the client input variables
  },
  serialize(value: ObjectId) {
    return value.toHexString(); // value sent to the client
  },
  parseLiteral(ast) {
    if (ast.kind === Kind.STRING) {
      return new ObjectId(ast.value); // value from the client query
    }
    return null;
  },
});

and date...

import { GraphQLScalarType, Kind } from "graphql";

export const GraphQLISODateTime = new GraphQLScalarType({
  name: "DateTime",
  description:
    "The javascript `Date` as string. Type represents date and time as the ISO Date string.",
  parseValue(value: string) {
    return new Date(value);
  },
  serialize(value: Date) {
    if (!(value instanceof Date)) {
      throw new Error(`Unable to serialize value '${value}' as it's not instance of 'Date'`);
    }
    return value.toISOString();
  },
  parseLiteral(ast) {
    if (ast.kind === Kind.STRING) {
      return new Date(ast.value);
    }
    return null;
  },
});

@burner986
Copy link

As long as your scalar type is ObjectId and not string it works just fine. same with date BTW.

or make your own...
ObjectId

import { GraphQLScalarType, Kind } from "graphql";
import { ObjectId } from "mongodb";

export const ObjectIdScalar = new GraphQLScalarType({
  name: "ObjectId",
  description: "Mongo object id scalar type",
  parseValue(value: string) {
    return new ObjectId(value); // value from the client input variables
  },
  serialize(value: ObjectId) {
    return value.toHexString(); // value sent to the client
  },
  parseLiteral(ast) {
    if (ast.kind === Kind.STRING) {
      return new ObjectId(ast.value); // value from the client query
    }
    return null;
  },
});

and date...

import { GraphQLScalarType, Kind } from "graphql";

export const GraphQLISODateTime = new GraphQLScalarType({
  name: "DateTime",
  description:
    "The javascript `Date` as string. Type represents date and time as the ISO Date string.",
  parseValue(value: string) {
    return new Date(value);
  },
  serialize(value: Date) {
    if (!(value instanceof Date)) {
      throw new Error(`Unable to serialize value '${value}' as it's not instance of 'Date'`);
    }
    return value.toISOString();
  },
  parseLiteral(ast) {
    if (ast.kind === Kind.STRING) {
      return new Date(ast.value);
    }
    return null;
  },
});

I also am trying to learn graphql with this library and encountered the same problem. Yup this helped me

@thardy
Copy link

thardy commented Jun 12, 2020

When I try the above custom scalar type code, I receive...

Argument type {name: string, description: string, parseValue(=): , serialize(): , parseLiteral(): ( | null)} is not assignable to parameter type GraphQLScalarTypeConfig<*, *>

I think that's just a warning from my IDE. The code compiles, but at runtime I receive the error...
TypeError: graphQLType.getFields is not a function

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants