Node Exercise Tracker Microservice Project: "The response returned from `POST /api/users/:_id/exercises` will be the user object with the exercise fields added"

I’ve been working on the exercise tracker microservice project for the past several days and can’t seem to pass the “The response returned from POST /api/users/:_id/exercises will be the user object with the exercise fields added” test.

Looking at the code for the test, I did my best to troubleshoot by building the deepEqual assertion into the route itself. So my route is currently written as follows:

// create an exercise for a user
app.post('/api/users/:_id/exercises', async function(req, res) {
  console.log("In the exercises/workouts POST request");
  // the body looks like this:
  // {":_id":"66c4fac95d65b665ec1e721b","description":"running","duration":"50","date":"2024-08-20"}
  const user_id = req.params._id;
  const description = req.body.description;
  const duration = req.body.duration;
  const date = req.body.date;
  console.log(`${user_id}, ${description}, ${duration}, ${date}`)

  try {
    const user = await User.findById(user_id);
    if (!user) {
      res.send("Could not find user.")
    } else {
      const workoutDocument = new Workout({
        user_id: user._id,
        description: description,
        duration: duration,
        // if no date is provided, use the current date
        date: date ? new Date(date).toDateString() : new Date().toDateString()
      });
      try {
        // save the new workout to the database
        const workout = await workoutDocument.save();
        console.log(JSON.stringify(workout.date.toDateString()), typeof(JSON.stringify(workout.date.toDateString())))
        console.log(`
          ${user.username, typeof(user.username)},
          ${workout.description, typeof(workout.description)},
          ${workout.duration, typeof(workout.duration)},
          ${workout.date.toDateString(), typeof(workout.date)},
          ${workout._id, typeof(workout.user_id)},
        `)
        console.log(deepEqual(JSON.stringify(workout), JSON.stringify({
          username: user.username,
          usernameType: typeof(user.username),
          description: workout.description,
          descriptionType: typeof(workout.description),
          duration: Number(workout.duration),
          durationType: typeof(workout.duration),
          date: workout.date.toDateString(),
          dateType: typeof(workout.date.toDateString()),
          _id: workout._id,
          _id: workout.user_id
        })))
        res.json({
          username: user.username,
          usernameType: typeof(user.username),
          description: workout.description,
          descriptionType: typeof(workout.description),
          duration: Number(workout.duration),
          durationType: typeof(workout.duration),
          date: workout.date.toDateString(),
          dateType: typeof(workout.date.toDateString()),
          _id: workout._id,
          _id: workout.user_id
        })
      } catch (err) {
        console.log(err);
        res.send(`There was an error with saving the workout: ${err}`);
      }
    }
  } catch (err) {
    console.log(err);
    res.send(`There was an error with retrieving the user: ${err}`);
  }
});

When I run the project locally and try to add an exercise in the UI using the route as coded above, I get the following error:

AssertionError [ERR_ASSERTION]: Expected values to be loosely deep-equal:

'{"user_id":"66cf57b82fb30bf35d5e46a1","description":"running","duration":20,"date":"2024-08-28T04:00:00.000Z","_id":"66cf95835c60fac6dc377d6c","__v":0}'

should loosely deep-equal

'{"username":"dylanc","usernameType":"string","description":"running","descriptionType":"string","duration":20,"durationType":"number","date":"Wed Aug 28 2024","dateType":"string","_id":"66cf57b82fb30bf35d5e46a1"}'
    at /Users/mgermaine93/Desktop/CODE/fcc-code-challenges/back-end-development-and-apis/projects/exercise-tracker-microservice/index.js:144:21
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
  generatedMessage: true,
  code: 'ERR_ASSERTION',
  actual: '{"user_id":"66cf57b82fb30bf35d5e46a1","description":"running","duration":20,"date":"2024-08-28T04:00:00.000Z","_id":"66cf95835c60fac6dc377d6c","__v":0}',
  expected: '{"username":"dylanc","usernameType":"string","description":"running","descriptionType":"string","duration":20,"durationType":"number","date":"Wed Aug 28 2024","dateType":"string","_id":"66cf57b82fb30bf35d5e46a1"}',
  operator: 'deepEqual'
}

It looks like the actual and expected values don’t quite match up, particularly with the date, user_id, and _id values. Ignoring removing the ...Type keys and values from my expected output, I’m not sure how to fix this. Any ideas?

All of the other tests are passing. I’m running this locally. The code for my entire exercise tracker project is here.

Thank you in advance.

The only thing you are asked to respond with is the username, description, duration, date, and _id

The example response

{
  username: "fcc_test",
  description: "test",
  duration: 60,
  date: "Mon Jan 01 1990",
  _id: "5fb5853f734231456ccb3b05"
}

When I clean up your response in the route, your code passes all the tests.

Thank you for responding, @lasjorg .

Hmm, I noticed that and fixed it, but for some reason I’m still not able to pass all of the tests like you are. I’ve been fiddling with the deepEqual test a bit more in the route itself (which is commented out below) to try and understand what’s going on.

Here’s my updated route:

// create an exercise for a user
app.post('/api/users/:_id/exercises', async function(req, res) {
  console.log("In the exercises/workouts POST request");
  // the body looks like this:
  // {":_id":"66c4fac95d65b665ec1e721b","description":"running","duration":"50","date":"2024-08-20"}
  const user_id = req.params._id;
  const description = req.body.description;
  const duration = req.body.duration;
  const date = req.body.date;

  try {
    const user = await User.findById(user_id);
    if (!user) {
      res.send("Could not find user.")
    } else {
      const workoutDocument = new Workout({
        user_id: user._id,
        description: description,
        duration: duration,
        // if no date is provided, use the current date
        // date: date ? new Date(date).toDateString() : new Date().toDateString()
        date: date ? new Date(date) : new Date(),
        username: user.username
      });
      try {
        // save the new workout to the database
        const workout = await workoutDocument.save();
        const actual = JSON.stringify(workout)
        const expected = JSON.stringify({
          user_id: user._id,
          description: workout.description,
          duration: Number(workout.duration),
          date: new Date(workout.date),
          username: user.username,
        })

        console.log(`Here is the ACTUAL: ${actual}`);
        console.log(`Here is the EXPECTED: ${expected}`);
        // console.log(deepEqual(actual, expected));
        res.json({
          _id: user._id,
          username: user.username,
          description: workout.description,
          duration: Number(workout.duration),
          date: new Date(workout.date).toDateString()
        })
      } catch (err) {
        console.log(err);
        res.send(`There was an error with saving the workout: ${err}`);
      }
    }
  } catch (err) {
    console.log(err);
    res.send(`There was an error with retrieving the user: ${err}`);
  }
});

Here’s what I’m seeing for one of the tests, where I print out the actual and expected values in the route:

In the exercises/workouts POST request
Here is the ACTUAL: {"user_id":"66d213daf4422fe1e21b3c4a","description":"test","duration":60,"date":"1990-01-03T00:00:00.000Z","username":"fcc_test_17250436747","_id":"66d213daf4422fe1e21b3c50","__v":0}
Here is the EXPECTED: {"user_id":"66d213daf4422fe1e21b3c4a","description":"test","duration":60,"date":"1990-01-03T00:00:00.000Z","username":"fcc_test_17250436747"}

Based on some of the other forum posts I’ve looked up, it seems that GMT/time might be an issue (I’m in GMT-04:00). I wonder if that would be a reason you’re able to get all of the tests to pass and not me?

EDIT:

Forgot to mention that I updated my workoutSchema to be the following, which isn’t seen in the code snippet above. I added the username property for test purposes:

// the schema used for workouts/exercises
const workoutSchema = new Schema({
  user_id: {
    type: String,
    required: true
  },
  description: {
    type: String,
    required: true
  },
  duration: {
    type: Number,
    required: true
  },
  date: {
    type: Date,
    required: false
  },
  username: {
    type: String,
    required: false
  }
});
// compile model from schema
const Workout = mongoose.model("Workout", workoutSchema);

Your repo code is passing for me (I just update the index with your code).


If you think it is related to the timezone, you can try using Gitpod, Replit, Glitch and see if that works. Or set your PC clock to UTC +1 (which works for me).

Edit: I just tested it with UTC-4 and UTC-6, and I’m still passing all the tests.

1 Like

Thanks again, @lasjorg .

That’s bizarre. I just tested with the gitpod version (simply started the boilerplate project there, updated the .env file, updated and installed the dependencies, and then copy/pasted my index.js file in there) and it passed the tests right away.

So something must be different between gitpod and my local machine.

I’m just relieved that I’m finally passing all of the tests, because I knew that I had it correct. Really appreciate your time and attention to this.

1 Like