简体   繁体   中英

Grabbing the ID of a linked object with GraphQL, Apollo and React

I'm building an event managing database that handles RSVPs and links those RSVPs to a specific event. I'm using React, Apollo, GraphQL and Prisma as my stack and am having trouble correctly writing a mutation that would link an RSVP to an existing event. Still relatively new to the syntax, but I can't grab the event.id when I'm using the createRsvp mutation.

I'm able to pass the event.id down on the front-end through props, and I think a less-elegant way of receiving event.id in the args of the RSVP would be creating a hidden form with the event.id, but I KNOW there's got to be a way through graphQL. I've tried looking through the docs and various examples on grabbing the id from a different object. Any help is much appreciated :)

On the backend, here's my datamodel:

    type Rsvp {
      id: ID! @id
      event: Event! @relation(link: INLINE)
      firstName: String!
      lastName: String!
      email: String! @unique
      company: String
      jobTitle: String
      mobile: String
      dietary: String
    }

    type Event {
      id: ID! @id
      isPublished: Boolean
      title: String!
      startDate: String!
      endDate: String!
      description: String!
      image: String
      address: String
      url: String!
      suburb: String
      postcode: String
      state: String
      country: String
      guestLimit: Int
      rsvps: [Rsvp]
    }

The actual resolver for the Mutation.. I think I'm incorrectly retrieving the event.id here. My though process is that data: {...args} is first taking in the data from the RSVP form, and the connection to event is linking it to a certain event.

async createRsvp(parent, args, ctx, info) {
    // 1. Query the event that is being registered for
    const eventId = ctx.request.event.id;
    // 2. Create the RSVP for this specific event
    const rsvp = await ctx.db.mutation.createRsvp(
      {
        data: {
          ...args,
          event: {
            connect: { id: eventId }
          }
        }
      },
      info
    );
    console.log(rsvp);
    return rsvp;
  }
};

On the front end, this is what my Mutation looks like

const RSVP_MUTATION = gql`
  mutation RSVP_MUTATION(
    $email: String!
    $firstName: String!
    $lastName: String!
    $company: String
    $jobTitle: String
    $mobile: String
    $dietary: String
  ) {
    createRsvp(
      email: $email
      firstName: $firstName
      lastName: $lastName
      company: $company
      jobTitle: $jobTitle
      mobile: $mobile
      dietary: $dietary
    ) {
      id
    }
  }
`;

and finally, the Mutation function in the form:

<Mutation mutation={RSVP_MUTATION} variables={({ id }, this.state)}>
              {(createRsvp, { loading, error }) => (
                <Form
                  onSubmit={async e => {
                    e.preventDefault();
                    const res = await createRsvp();
                  }}>

The error I receive in the console is "Uncaught (in promise) Error: GraphQL error: Cannot read property 'id' of undefined" which leads me to believe I'm incorrectly trying to access the event.id. Any tips or advice? Thanks again!

Divide and conquer

You can use /graphiql playground to test queries and mutations (API generally).

Testing this mutation:

mutation RSVP_MUTATION(
  $email: String!
  $firstName: String!
  $lastName: String!
  $company: String
  $jobTitle: String
  $mobile: String
  $dietary: String
) {
  createRsvp(
    email: $email
    firstName: $firstName
    lastName: $lastName
    company: $company
    jobTitle: $jobTitle
    mobile: $mobile
    dietary: $dietary
  ) {
    id
  }
}

... with required variables you should quickly notice that you need to pass event id as variable, too. No special (more/less elegant), separate method required, this is a standard, query/mutation and variables, nothing more !!!

Just add eventId variable:

mutation RSVP_MUTATION(
  $eventId: ID!
  $email: String!
  $firstName: String!
  $lastName: String!
  $company: String
  $jobTitle: String
  $mobile: String
  $dietary: String
) {
  createRsvp(
    eventId: $eventId
    email: $email
    firstName: $firstName
    lastName: $lastName
    company: $company
    jobTitle: $jobTitle
    mobile: $mobile
    dietary: $dietary
  ) {
    id
  }
}

Of course in resolver you'll get it within args , you can use fe

const { eventId, ...rest } = args;
const rsvp = await ctx.db.mutation.createRsvp(
  {
    data: {
      ...rest,
      event: {

React variables can be passed fe by

variables={{ eventId: id, ...this.state }} 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM