I've got the following mutation resolver; ``` asyn...
# orm-help
j
I've got the following mutation resolver;
Copy code
async createCheckIn(parent, { title, location }, context) {
    const userId = getUserId(context);
    const { geonameId, ...rest } = location;
    if (!location || !geonameId) {
      throw new Error(`CheckIn must include a valid location`);
    }
    return context.prisma.createCheckIn({
      title,
      location: {
        upsert: {
          where: {
            geonameId
          },
          update: { ...rest },
          create: { ...location }
        }
      },
      public: true,
      user: { connect: { id: userId } }
    });
  }
But I'm getting an error that says "Field 'upsert' is not defined in the input type". Does anyone see what I'm doing wrong here?
c
whats the input type of location
like whats the datamodel schema look lik
is there an upsertLocation function if you look at graphql playground?
j
In my schema.graphql I have;
Copy code
type Mutation {
  createCheckIn(title: String, location: LocationInput!): CheckIn!
}

type CheckIn {
  id: ID!
  public: Boolean
  title: String
  location: Location!
  user: User!
  createdAt: String!
}

type Location {
  id: ID!
  geonameId: String
  city: String
  regionName: String
  countryName: String
  latitude: String
  longitude: String
  checkIns: [CheckIn!]
}

input LocationInput {
  geonameId: String
  city: String
  regionName: String
  countryName: String
  latitude: String
  longitude: String
}
c
you mean your prisma.datamodel?
j
prisma.datamodel has;
Copy code
type CheckIn {
  id: ID! @unique
  createdAt: DateTime!
  updatedAt: DateTime!
  public: Boolean @default(value: "true")
  title: String
  location: Location! @relation(name: "CheckInToLocation")
  user: User! @relation(name: "UserCheckIn")
}

type User {
  id: ID! @unique
  email: String! @unique
  password: String!
  name: String!
  checkIns: [CheckIn!] @relation(name: "UserCheckIn")
  following: [User!] @relation(name: "Follow")
  followers: [User!] @relation(name: "Follow")
}

type Location {
  id: ID! @unique
  geonameId: String! @unique
  city: String
  regionName: String
  countryName: String
  latitude: String
  longitude: String
  checkIns: [CheckIn!] @relation(name: "CheckInToLocation")
}
c
you have type overwritten in your schema...
does that work?
j
I don't understand what you mean
c
don't the schemas get merged
well for me, my prisma types get imported into my gql server
I can't have a typed defined in two places
j
I don't think so... I got here by following https://www.howtographql.com/graphql-js/0-introduction/
c
you have location defined in both
j
AFAIK, datamodel is for Prisma and schema is for graphql-yoga
c
yes I know
j
Everything in datamodel.prisma is also in my schema
c
but on the default setup they get merged
right
because they are merged
but you have a type of the same name defined twice
Location is deffined twice
j
Yes, and so is User and so is CheckIn
Because that's how I was told I had to do it
c
weird, I thought you specifically couldn't do that
but maybe you can, I don't do that
j
It's been working for me so far... but this upsert thing isn't working
c
if I have a type in prisma.datamodel it is pulled in automatically to schema.graphql through the schema merge
but w/e that wouldn't change the upsert function
j
What can I look for in the playground?
c
well I goto the prisma playground
and see if you have a gql function called upsertLocation
j
How do I find that?
I'm on the playground
c
have you used the playground?
j
But how do I look for functions?
c
they are on the right
the schema
like a panel that comes out
j
This is what I see
c
should be a list of mutations and queries
j
Yeah...
Not sure why I would see anything about upsert here
c
yea, you dont have upsertLocation
for some reason
wait
thats not prisma
you are looking at the playground for yoga
should be two, like on mine its like this
j
No, it's my GraphQL server... there's a separate playground for Prisma?
c
yes
j
How do I access that?
c
j
Oh, found it...
Let me see what's here.... this is all generated stuff...
c
yea
but its saying it cant find the generated function
for upsert for the location type
j
I see this;
Copy code
input LocationUpsertWithoutCheckInsInput {
  update: LocationUpdateWithoutCheckInsDataInput!
  create: LocationCreateWithoutCheckInsInput!
}
c
playing with mine actually
looking at it
so... looking at it
it seems you cant do a nested upsert on create
you can only do it on update
I am guessing that is a limitation because the parent node wouldn't be created yet
j
Hmph.... That's frustrating... where did you get that information?
c
so they must make you create seperately
im just playing with my server, if you use playground it autocompletes
and I noticed on my create functions I could do a nested create
and on my update functions I could do a nested upsert and update
j
Ah, I see
c
and create
not sure why that is
its weird cause you can create on a create
I don't work at prisma, just use it
j
So in my resolver function could I do
context.prisma.createLocation()
and then
context.prisma.createCheckIn()
? In the same function?
c
of course
you would just want to
await
the first one
and your first one would be an upsert not a create
context.prisma.upsertLocation()
and then take its id and do a
connect
on the
createCheckin
they say they implemented nested upserts on create, I guess it hasn't made it into the current version yet
or if your version is old you could try updating
oh nm, the guy misspoke
reading further
his answer
Copy code
@nolandg : Ah i misunderstood this issue then. Thanks for bringing this to our attention pray . That original feature request does not make sense though with our semantics. An upsert in our API either update the connected node or create a new node and connect it.
So i guess what we really want is an connectOrCreate.
and they have a proposed solution, not implemented yet
j
Cool cool
does
context.prisma.upsertLocation({})
return something? An object?
c
yea
it returns the created object
so you could do like
const { id } = await context.prisma.upsertLocation({...blah})
then on the next one
Copy code
{
... 
location: {
   connect: {
     id
   }
}
sorry missed the await there
cause it returns a promise which returns the obj
j
Nice
Cool, thanks!
c
np
j
It's working! Thanks so much for your help @CCBCodeMonkey 🙂 This was the last piece I needed to finish what I set out to accomplish this morning on my side project
🦜 1
c
no prob! have a good night
and you learned about some of the tooling
that playground is super helpful
I usually write my queries to prisma there first
cause it auto completes and makes it easy to test to see if you have errors
then I paste it over(though now that I have been doing it more I can usually write it without the playground)