reactjsgraphqlapollographql-mutation

Updating model with GraphQL Mutation


I have been having trouble figuring out how to update a User with graphQL. The functionality I'm currently aiming for is for the user to be able to update their account/profile information. I have some things set up for the user like a bio field for their profile, and a profile picture field that's set up to take a URL and display that as their profile picture.

I have no problems when it comes to creating using graphQL. A user can sign up, log in, make posts, etc without issue. I can also update the User in regards to other models, for example, a new post pushes to the users Post data just fine.

I have not been able to figure out how to update a user directly though. Essentially I can get around this by creating a new model for "profile pic" and pushing that to the User, but that seems like it's just extra steps that might slow things down, as well as shortchanging myself being able to learn something new.

This is the User model. I have omitted a few fields due to the exact block of code being large, but this includes the "image" and "bio" fields (the fields I would like to update) as well as the reference to the Post model which I mentioned above that functions appropriately.

User.js

const userSchema = new Schema(
    {
        username: {
            type: String,
            required: true,
            unique: true,
            trim: true
        },
        email: {
            type: String,
            required: true,
            unique: true,
            match: [/.+@.+\..+/, 'Must match an email address!']
        },
        password: {
            type: String,
            required: true,
            minlength: 8
        },
        image: {
            type: String
        },
        bio: {
            type: String,
            maxLength: 500
        },
        posts: [
            {
                type: Schema.Types.ObjectId,
                ref: 'Post'
            }
        ],

    },

Below is the mutation in Explorer, including the variables and the result.

Explorer Mutation

Profile Pic Resolver

        addProfilePic: async (parent, { image }, context) => {
            if (context.user) {
                const updatedUser = await User.findOneAndUpdate(
                    { _id: context.user._id },
                    { image: image },
                    { new: true, runValidators: true }
                );

                return updatedUser;
            }

            throw new AuthenticationError('You need to be logged in!');
        },

typeDefs.js (relevant only)

    type Mutation {
        addProfilePic(_id: ID!, image: String!): Auth
    }

I notice that in the Explorer page it returns "null" for user with a 200 status. I am led to believe that means that it's not able to even access the "image" field on the user to be able to update it. When compared to my other mutations in regards to users, this is set up very similarly and I'm not sure what the difference is.

I feel like I am missing something very basic here in regards to being able to update. I haven't been able to find an update mutation example that works. Could anyone assist? My main questions would be:

  1. Why does the mutation return "null" for user?

  2. How can I set up my resolver to appropriately update information on an already-created object?

Thank you to anyone who is able to take a look and assist, I will be closely watching this post for replies and will update any other code someone may need to be able to assist. I've been stuck in regards to updating information for a long time, but my site is getting to the point where it's nearly ready and I need to tackle this updating issue in order to progress. Thank you!

Quick Edit: I want to add that "Auth" is referenced. The appropriate authorization headers are in place to retrieve the data. Just wanted to add that in as I highly doubt authorization has anything to do with this!


Solution

  • I have solved this issue and would like to leave the answer here for anyone who may find it useful.

    In the mutation typeDefs, I changed the "Auth" to "User",

        type Mutation {
            addProfilePic(_id: ID!, image: String!): User
        }
    

    and then in the mutation itself, took away the user field like such:

        mutation addProfilePic($_id: ID!, $image: String!) {
            addProfilePic(_id: $_id, image: $image) {
                    _id
                    username
                    image
            }
        }
    

    This has allowed the user to update their profile photo information. Hope this helps!