2
votes

So I'm having issues trying to resolve a mutation that contains nested input types from another input type, correct me if I'm doing a wrong design with the models.

This is the mutation, I'm using Playground to check it out:

mutation{
  createOrganization(
    name: "Bitas"
    staff: [
      {
        firstName: "Albert"
        lastName: "Chavez"
        position: "Developer"
        contactInformation:[
            {
                email: "[email protected]"
                phone:"9187631"
                linkedin: "whatever"
            },
            {
                email: "[email protected]"
                phone:"91876312"
                linkedin: "whatever2"
            }
          ]
        }
    ]
  ){
    name
    staff{
      firstName
      contactInformation{
        email
      }
    }
  }
}

This mutation is creating a relationship between Organization and Employee, which at the same time is creating a relationship between Employee and Contact Information... here are the schemas:

type Organization {
    id: ID!
    name: String!
    staff: [Employee!]!
}

type Employee {
    id: ID!
    firstName: String!
    lastName: String!
    position: String!
    contactInformation: [ContactInfo!]!
    belongsToOrg: Organization
}

input employeeInput {
    firstName: String!
    lastName: String!
    position: String!
    contactInformation: [contactInfoInput!]!
    belongsToOrg: ID
}

type ContactInfo {
    id: ID!
    email: String!
    phone: String!
    linkedin: String!
    belongsTo: Employee!
}

input contactInfoInput {
    email: String!
    phone: String!
    linkedin: String!
}

Correct me if I'm not creating the mutations correctly

type Mutation {
    createOrganization(name: String!, staff: [employeeInput!]): Organization!
    createEmployee(firstName: String!, lastName: String!, position:String!, contactInformation: [contactInfoInput!]!): Employee!
}

And here are the functions to create:

function createEmployee(parent, args, context, info) {
    return context.prisma.createEmployee({
        firstName: args.firstName,
        lastName: args.lastName,
        position: args.position,
        contactInformation: {
            create: args.contactInformation
        },
    })
}

function createOrganization(parent, args, context, info) {
    return context.prisma.createOrganization({
        name: args.name,
        staff: {
            create: args.staff
        }
    })
}

function staff(parent, args, context) {
    return context.prisma.organization({id: parent.id}).staff();
}

function contactInformation(parent, args, context) {
    return context.prisma.employee({id: parent.id}).contactInformation()
}

function belongsTo(parent, args, context) {
    return context.prisma.contactInfo({id: parent.id}).belongsTo()
}

So when I hit the mutation on Playground, it gives me the error:

Reason: 'staff.create[0].contactInformation' Expected 'ContactInfoCreateManyWithoutEmployeeInput', found not an object.

Could please somebody explain me what this means?? Am I not designing correctly the schema or relationships?? Or perhaps is because too many levels of nested inputs?? If I console.log the contactInformation field on the createOrganization function the value is undefined.

Note: When creating a Employee, the nested mutation works fine.

Thanks in advance.

1

1 Answers

1
votes

The issue is in input passed to prisma binding function.

Let us start by looking at createOrganization mutation. This is how field definition for createOrganization mutation looks like - createOrganization(name: String!, staff: [employeeInput!]): Organization! where staff is relational field of type employeeInput which looks as below:

input employeeInput {
    firstName: String!
    lastName: String!
    position: String!
    contactInformation: [contactInfoInput!]!
    belongsToOrg: ID
}

Note that ContactInformation field here is array of contactInfoInput which looks like:

type ContactInfo {
    id: ID!
    email: String!
    phone: String!
    linkedin: String!
    belongsTo: Employee!
}

If we look at schema generated by Prisma, you will notice that for each relation field, we have nested mutation fields - create, connect, update, upsert etc. and when we call prisma binding, we need to adhere to Prisma's schema.

Now, if we look at resolver,

function createOrganization(parent, args, context, info) {
    return context.prisma.createOrganization({
        name: args.name,
        staff: {
            create: args.staff
        }
    })
}

args.staff is correctly being passed as create input here but problem is in contactInformation array present in args.staff. Its value does not match with ContactInfoCreateManyWithoutEmployeeInput type defined in Prisma's schema. Changing above resolver to following will fix issue for you but I would suggest better designing input types for mutations:

function createOrganization(parent, args, context, info) {
    const { staff } = args
    return context.prisma.createOrganization({
        name: args.name,
        staff: {
            create: staff.map((emp) => ({
               firstName: emp.firstName,
               lastName: emp.lastName,
               position: emp.position,
               contactInformation: {
                   create: emp.contactInformation || []
               }
            }))
        }
    })
}