GraphQL resolver logic - Call query/mutation from mutation?

Viewed 261

I am creating a workout/exercise logger, where user's can add a log of their set of an exercise to their account. User's will also be able to see their history of workouts and exercises (with set data). I am using mongoDB to store this data, with GraphQL and mongoose to query and mutate the data. I have seperated workout and exercise into their own types, as a workout object will only hold exercises and the sets that were recorded in the last 4 hours (duration of workout), while the exercise object will hold all sets that were ever logged by the user.

Type Definitions

type Workout {
  id: ID!
  workoutName: String!
  username: String!
  createdAt: String
  exercises: [Exercise]!
  notes: String
}
    
type Exercise {
  id: ID!
  exerciseName: String!
  username: String!
  sets: [Set]!
}

type Set {
  id: ID!
  reps: Int!
  weight: Float!
  createdAt: String!
  notes: String
}

My problem lies in my resolver code for adding a set (mutation). This resolver should:

  1. Query the database whether the exercise has ever been done by the user, by checking the name of the exercise with a match in the database, if there is a match, add the set data the user inputted to it, otherwise, create a new exercise entry first and then add the set to it.
  2. Query the database whether there is a workout that has been done in the last 4 hours. If there isn't a match, create a new workout entry in the database. If there is a workout, check for a matching exercise name on the workout object to add the set data to or create a new exercise entry for it.

I realise that this mutation will be fairly large and will combine both the querying and mutation of data together. So I'm wondering if I can call seperate queries/mutations from my addSet resolver similar to a function call? Or is there another method that I should be going about this?

addSet Resolver

async addSet(_, { exerciseName, reps, weight, notes }, context) {
            const user = checkAuth(context); // Authenticates and gets logged in user's details

            if (exerciseName.trim() === '') {
                throw new UserInputError('Empty Field', {
                    // Attached payload of errors - can be used on client side
                    errors: {
                        body: 'Choose an exercise'
                    }
                })
            } else {
                exerciseName = exerciseName.toLowerCase();
                console.log(exerciseName);
            }

            if ((isNaN(reps) || reps === null) || (isNaN(weight) || reps === null)) {
                throw new UserInputError('Empty Fields', {
                    // Attached payload of errors - can be used on client side
                    errors: {
                        reps: 'Enter the number of reps you did for this set',
                        weight: 'Enter the amount of weight you did for this set'
                    }
                })
            }

            // TODO: Check to see if the exercise has been done before by the user. If it has, then update the entry by adding the set data to it. If not create a new entry for the 
            // exercise and then add the data to it - Completed and working.
            const exerciseExists = await Exercise.findOne({ exerciseName: exerciseName, username: user.username });

            if (exerciseExists) {
                console.log("This exercise exists");
                exerciseExists.sets.unshift({
                    reps,
                    weight,
                    username: user.username,
                    createdAt: Date.now(),
                    notes
                })
                await exerciseExists.save();
                //return exerciseExists;
            } else {
                console.log("I don't exist");
                const newExercise = new Exercise({
                    exerciseName,
                    user: user.id,
                    username: user.username,
                });
                const exercise = await newExercise.save();
                console.log("new exercise entry");
                exercise.sets.unshift({
                    reps,
                    weight,
                    username: user.username,
                    createdAt: Date.now(),
                    notes
                })
                await exercise.save();
                //return exercise;
            }

            // TODO: Get the most recent workout from the user and check if the time it was done was from the last 4 hours. If it wasn't, create a new workout entry for the user. 
            // If it was within the ast 4 hours, check to see if the workout has an exercise that matches with one the user inputted. If there isn't an exercise, create a new entry 
            // and add the set data to it, otherwise update the existing entry for the exercise.
            const workoutExists = await Workout.findOne({ username: username }).sort({ createdAt: -1 }); // Gets most recent workout by user
            const now = Date.now();
            if (now > workoutExists.createdAt + 14400000) { // Checks to see if the workout was less than 4 hours ago
                console.log("workout was from another session");
                // rest of code not implemented yet
            } else {
                console.log("workout is still in progress");
                // rest of code not implemented yet
            }

        },
0 Answers
Related