Thomas
Thomas

Reputation: 2386

GraphQL - passing an ObjectType a parameter

I'm using GraphQL and it's working great, however, I can't seem to figure out how to pass a parameter into the fields section of my Event GraphQLObjectType.

I would like to be able to pass in the currentUserId (which is given to me through a token) into the Event GraphQLObjectType so I can add in an isAttending attribute.

I've attached code with comments of what I'm basically trying to do:

const Event = new GraphQLObjectType({
  name: 'Event',
  description: 'This represents an Event',
  fields: (currentUserId) => { // currentUserId is the parameter I would like to pass in 
    return {
      id: {
        type: GraphQLInt,
        resolve (event) {
          return event.id;
        }
      },
      title: {
        type: GraphQLString,
        resolve (event) {
          return event.title;
        }
      },
      attendees: {
        type: new GraphQLList(User),
        resolve (event) {
          return event.getAttendees()
        }
      },
      // this is what I would like to do
      isAttending: {
        type: GraphQLBool,
        resolve (event) {
          return event.getAttendees({
            where: {
              id: currentUserId // that's the parameter I would like pass in
            }
          }).then(attendee => {
            return (attendee.length > 0 ? true : false);
          )};
        }
      }
      // end of what I'm trying to do //
    };
  }
});

const Query = new GraphQLObjectType({
  name: 'Query',
  description: 'Root query object',
  fields: () => {
    return {
      events: {
        type: new GraphQLList(Event),
        args: {
          id: {
            type: GraphQLInt
          }
        },
        resolve (root, args) {
          // here is the parameter I would like to pass to the event object
          let currentUserId = root.userId; 
          ////////

          return Db.models.event.findAll({ where: args });
        }
      },
      ...

Update

The reason I can't just do data.currentUserId = root.userId, is because it's not visible when I'm returned a collection of event objects, since what is passed into my Event GraphQLOBjectType is only the {event} object.

What it looks like when I do data.currentUserId and there is an array of objects inside data is this:

[{objects}, currentUserId: 1] 

As opposed to what we want which is this:

[{object, currentUserId: 1}, {anotherObject, currentUserId: 1}] 

If I wanted to have access to the currentUserId in the Event GraphQLObject, the only thing I can think of is to loop through every object and add the currentUserId onto it like this:

return events.map(event => { 
  event.currentUserId = currentUserId; 
  return event; 
});`

Is this the best solution?

Upvotes: 2

Views: 2151

Answers (1)

LordDave
LordDave

Reputation: 1128

I'm afraid you can't do that. fields doesn't recieve any parameters, so you won't send any either.

Fortunately, you can achieve that in more convenient way.

Everything your parent type (Query) returns in resolve function is visible in child resolve's root parameter.

const Query = new GraphQLObjectType({
    name: 'Query',
    description: 'Root query object',
    fields: () => ({
            events: {
                type: new GraphQLList(Event),
                args: {
                    id: {
                        type: GraphQLInt
                    }
                },
                resolve (root, args) {

                    return Db.models.event.findAll({ where: args })
                            .then(data => {
                                // pass the parameter here
                                data.currentUserId = root.userId;
                                return data;
                            });
                }
            },
            ...

Then your Event object would look like this:

const Event = new GraphQLObjectType({
    name: 'Event',
    description: 'This represents an Event',
    fields: () => ({

        ...

        isAttending: {
            type: GraphQLBool,
            resolve: (event) => {
                return event.getAttendees({
                    where: {
                        id: event.currentUserId // that's the parameter you've passed through parent resolve
                    }
                }).then(attendee => {
                    return (attendee.length > 0 ? true : false);
                });
            }
        }
    })
});

Upvotes: 5

Related Questions