Prisma1: Aggregate-count on connection returning null on non-nullable field

Created on 5 Feb 2019  路  4Comments  路  Source: prisma/prisma1

Describe the bug
Aggregate-count is not working properly when implementing a resolver

To Reproduce
Steps to reproduce the behavior:

  1. Start prisma with the following datamodel:
type Person {
  id: ID! @unique
  name: String!
}
  1. Start with the following schema:
type PageInfo {
  hasNextPage: Boolean!
  hasPreviousPage: Boolean!
  startCursor: String
  endCursor: String
}

type Person {
  id: ID!
  name: String!
}

type PersonConnection {
  pageInfo: PageInfo!
  edges: [PersonEdge]!
  aggregate: AggregatePerson!
}

type PersonEdge {
  node: Person!
  cursor: String!
}
type Query {
  personConnection: PersonConnection!
}

However :

export const QueryResolvers = {
  // This returns error "Cannot return null for non-nullable field PersonConnection.aggregate"
  async personConnection(parent, args, context, info) {
    return await prisma.personsConnection()
  }

  // This works
  async personConnection(parent, args, context, info) {
    const aggregate = await prisma.personsConnection().aggregate()
    const pageInfo = await prisma.personsConnection().pageInfo()
    const edges = await prisma.personsConnection().edges()
    return {aggregate, pageInfo, edges}
  }
}

Expected behavior
I didn't quite expect the hack to work, and I don't quite know what the problem is. However, I do expect the aggregate count to work properly without me having to repeat myself thrice :)

Screenshots
If applicable, add screenshots to help explain your problem.

Versions (please complete the following information):

  • Connector: Postgres
  • Prisma Server: 1.25
  • prisma CLI: [e.g. prisma/1.24.0 (darwin-x64) node-v10.4.0]
  • OS: OSX high sierra
  • other dependencies: prisma-client, prisma-binding, etc. if applicable

Additional context
Add any other context about the problem here.

areapi kinduplicate

Most helpful comment

Just following up the above I found that

const resolvers = {
  PersonConnection:{
    aggregate: (parent, args, ctx) => {
      return prisma.personsConnection(args).aggregate();
    },
  },
  Query:{
    personConnection(parent, args, context, info) {
      return prisma.personsConnection()
    }
  }
}

Will never be passed valid 'args' and the aggregate count will always be the maximum count of persons.

If you instead modify the Query return to actually return each expected connection object:

 Query:{
    personConnection(parent, args, context, info) {
        const newReturn = {
            pageInfo: prisma.personsConnection(args).pageInfo(),
            edges: prisma.personsConnection(args).edges(),
            aggregate: prisma.personsConnection(args).aggregate()
        }
        return newReturn
    }
  }

You should get accurate aggregates

All 4 comments

@arnabkd : I believe what you are running into is this: https://github.com/prisma/prisma/issues/3513#issuecomment-439346021. The comment has a resolution.

If you agree that these are duplicate issues indeed, please feel free to close this issue and follow this one https://github.com/prisma/prisma/issues/3513 for a resolution.

P.S. The original approach should also work because we have implemented this opinionated API: https://github.com/prisma/prisma/issues/3309, https://github.com/prisma/prisma/issues/3629

I currently resolve the aggregate on each of the types like so:
https://github.com/javascript-af/javascript-af/blob/master/packages/backend/src/resolvers/Repo/RepoConnection.ts

(Also a small tip: You can directly return a promise from a resolver

So this will look something like this in your case:

const resolvers = {
  PersonConnection:{
    aggregate: (parent, args, ctx) => {
      return prisma.personsConnection(args).aggregate();
    },
  },
  Query:{
    personConnection(parent, args, context, info) {
      return prisma.personsConnection()
    }
  }
}

Now, you can easily fetch all of the stuff:
image

But I also feel this is a duplicate of #3513

Sorry for the late response, I thought I had closed and commented. My bad.
Yes, this does look like a duplicate.

Just following up the above I found that

const resolvers = {
  PersonConnection:{
    aggregate: (parent, args, ctx) => {
      return prisma.personsConnection(args).aggregate();
    },
  },
  Query:{
    personConnection(parent, args, context, info) {
      return prisma.personsConnection()
    }
  }
}

Will never be passed valid 'args' and the aggregate count will always be the maximum count of persons.

If you instead modify the Query return to actually return each expected connection object:

 Query:{
    personConnection(parent, args, context, info) {
        const newReturn = {
            pageInfo: prisma.personsConnection(args).pageInfo(),
            edges: prisma.personsConnection(args).edges(),
            aggregate: prisma.personsConnection(args).aggregate()
        }
        return newReturn
    }
  }

You should get accurate aggregates

Was this page helpful?
0 / 5 - 0 ratings