Dus
Dus

Reputation: 4240

nestjs : Define map/array to be used in mongoose and graphql

I'm working with nestJs and i'm trying to create a mutation which receives an array of key, values as a parameter. Also, i'm defining an ObjectType which will define the mongoose schema, and graphql objectType.

  1. CarName : the data of the array.
  2. SetCarParams : the input to the mutation.
  3. Car: The mongoose+graphql schema definition
import { Field, InputType, ObjectType } from '@nestjs/graphql';
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document } from 'mongoose';

@ObjectType()
export class CarName {
  @Field()
  key: string;

  @Field()
  value: string;
}

@InputType()
export class SetCarParams {
  @Field(() => [CarName])
  names: CarName[];
}

@Schema()
@ObjectType()
export class Car {
  @Prop({ type: [CarName] })
  @Field(() => [CarName])
  names: CarName[];
}

export type CarDocument = Car & Document;
export const CarDto = SchemaFactory.createForClass(Car);

@Mutation(() => Car)
  setCar(@Args(camelCase(Car.name)) carParams: SetCarParams) {
    console.log('do something');
}

The error i'm receiving : CannotDetermineInputTypeError: Cannot determine a GraphQL input type for the "names". Make sure your class is decorated with an appropriate decorator.

  1. when i set the type to be String and not CarName, my structore works.
  2. when i use raw type in the mongoose schema, it doesn't work as well
@Schema()
@ObjectType()
export class Car {
  @Prop(
    raw({
      type: Map,
      of: CarName,
    }),
  )
  @Field(() => [CarName])
  names: CarName[];
}
  1. Also, when i try to not use SetCarParams as an inputtype to the mutation, it doesn't work as well
@Mutation(() => Car)
  setCar(
    @Args('names', { type: () => [{ key: String, value: String }] })
    names: [{ key: string; value: string }],
  ) {

Upvotes: 3

Views: 2278

Answers (1)

Dus
Dus

Reputation: 4240

So, i figured out the issue - the naming of InputType and ObjectType collide. When i set an exact naming for those, it works like a charm.

import { Field, InputType, ObjectType } from '@nestjs/graphql';
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document } from 'mongoose';

@InputType('CarNameInput')
@ObjectType('CarNameType')
@Schema({ versionKey: false, timestamps: true })
export class CarName {
  @Prop()
  @Field(() => String)
  key: string;

  @Prop()
  @Field(() => String)
  value: string;
}

@InputType('CarInput')
@ObjectType('CarType')
export class Car {
  @Field(() => [CarName])
  carNames: Array<CarName>;
}

export type CarNameDocument = CarName & Document;
export const CarNameDto = SchemaFactory.createForClass(CarName);
import { Field, ObjectType, Mutation } from '@nestjs/graphql';
import { Schema } from '@nestjs/mongoose';

@ObjectType()
@Schema()
export class Identifier {
  @Field(() => String)
  id: string;
}

@Mutation(() => Identifier)
async addCar(@Args({ name: 'car', type: () => Car }) car: Car) {
  //TODO something
}

how i called the mutation in graphql :

mutation {
  addCar(
    car: {
      carNames: [
        { key: "asdf1", value: "hello" }
        { key: "asdf2", value: "world" }
      ]
    }
  ) {
    id
  }
}

Upvotes: 0

Related Questions