Exercise Tracker - Add Exercise

I have tried many methods and done a lot of digging on this, but I simply don’t understand why I can’t add an exercise to my users. The users are created correctly, with an empty array for the exercise field, but I can’t add an exercise to that array.

Here’s my mongoose model:

const mongoose = require( 'mongoose' );

const userSchema = new mongoose.Schema({
  username: {
    type: String,
    required: true,
    unique: true
  },
  exercise: [{
    description: String,
    duration: Number,
    date: { 
      type: Date, 
      default: Date.now,
    }
  }]
});

const User = mongoose.model( 'etUser', userSchema );

module.exports = User;

Actually, the exercise array does not give a default date, so that’s another issue, but I’m less concerned about that one at the moment.

And here’s my current iteration of an attempt to push onto that array:

app.post( "/api/exercise/add", ( req, res ) => {
  let data = req.body;
  let exercise = {
    description: data.description,
    duration: data.duration,
    date: data.date
  };
  
  dbUser.update(
    { _id: data.userId }, { 
    $push: { 
      exercise: { 
        description: data.description, 
        duration: data.duration
      } 
    }
  });
  
  res.send( exercise );
});

I’m only sending the exercise to get something back and to check that it’s sending what I want. It is.

Here’s the full code:

I appreciate your assistance in advance.

1 Like

Hi,

You should use upsert to create new data. So I would start by adding some options.

 dbUser.update({_id: data.userId
    },{
    $push: {
      exercise : {
        foo: bar,
        bar: foo          
        }}
    }, {
      upsert: true, new: true
    }, ( (err, user) => {
      if(err) throw err;
      // the 'user' variable will just confirm the data was saved.
    }));

1 Like

I’m dumb sometimes. I just came back here to update my own question because I realized I was missing the callback function and that’s why it wasn’t doing anything.

You’ve (correctly) got a callback in your suggestion, and I’ll add your proposed options as well. Thanks!

Hi don’t send the ‘user’ to the client - that info is just for confirmation.

Thanks for the help. Now that I’ve got it saving and all that appears to work as intended, that minor issue I mentioned is turning out to be a hassle to correct.

I can’t seem to get a default Date.now to populate if the user doesn’t provide a date. I’ve tried setting a default option in my user model:

date: {
    type: Date,
    default: Date.now
}

This is the recommendation from Mongoose docs. I’ve tried inserting it with a ternary operator in my exercise variable:

let exercise = {
    description: data.description,
    duration: data.duration,
    date: date === null ? Date.now : data.date
}

And I’ve tried setting a function to fire in that same place:
date: defaultDate( data.date )

const defaultDate = ( date ) => {
    if ( date === null ) {
        return Date.now // also tried 'new Date()'
    }
    
    return date
}

Nothing seems to work. If it manually enter a date in the field, it works fine, but the default behavior should use Date.now if no date is given.

I’m lost on this one; it doesn’t seem like it should be very complicated to do this.

In my variable I used new Date() rather than Date.now and it worked. (I also tried to use Date.now first but it set the date to null.) This is 4 months later, maybe you got it figured out already.

@JP-Dub,

Hi, thanks so much for your solution, it also solved my problem. I need to ask, where can I find $push in the mongoose docs?

Hi, I’m not sure if I found anything other than references to $push in the mongoose docs, but it’s there in the MongoDB documentation.

https://docs.mongodb.com/manual/reference/operator/update/push/index.html

1 Like

Perfect! Thanks very much! @JP-Dub