API Exercise Tracker can't figure out how to log

Hey there,

I’m struggling with the exercise tracker log.
Basically I know how to retreive the data for a user, how to retrieve the data for exercises of that user but I can’t figure out hot to put everything in the res.json and fulfill user story 5 and 6.

Plus I’ve no idea how to limit the search as asked from user story 7.

my replit https://replit.com/@Eidan78/boilerplate-project-exercisetracker#server.js

live version https://boilerplate-project-exercisetracker.eidan78.repl.co

Any help will be really really appreciated.

It looks like you defined two separate, unconnected, schema: one for user and another for exercise. But then, there’s no way to connect a user to this person’s exercises. I defined one schema for user but this User schema includes an array to store this user’s exercises. Something like

user : {
 name: String,
exercises:[ {description:String, duration: Number, date: Date} ]
}

When you add a new user, you start with an empty exercise array. When you add a new exercise for the existing user, you find this user, add new exercise to the exercise array, and save this user back.

For pulling out a user’s log of exercises, you need to find a way to retrieve data in array property of a model. Among different ways, I used an aggregate operation because it is the first way I found to do the job.

I just completed this challenge. It gave me a really hard time!

I agree with @twotani that you need to think about your schema. If you look at the data returned by freeCodeCamp for a user’s logs, you will notice that the logs are objects nested in the log array. I found the following resource very helpful in understanding this.

https://mongoosejs.com/docs/subdocs.html#subdocuments-versus-nested-paths

Once you have the Schema redefined, it should be relatively easy to get all logs for a given user as the data returned for the log array will already be nested.

For the next challenge, filtering by dates and limiting the data, I struggled for a couple of days trying to figure out how to filter the query, but I ended up giving up and instead requested the full document (for the given params._id) and used javascript functions to craft the response.

Hope this helps!

Thank you very much. I’ve changed the schema for the user, now I’ve to understand how to update it’s data and add info to the log array… :roll_eyes:

Thank you very much!

ok…thanks to your help I just miss the filtering part now. “just” :smiley:

Here’s a great article, by Nick Karnik, that complements the information covered in the course.
https://www.freecodecamp.org/news/introduction-to-mongoose-for-mongodb-d2a7aa593c57/

Towards the end of the article, you will find the following sample syntax for filtering a query. This is what I tried to implement but ended up going a different, much less elegant, route. Though, if you’re retrieving a single doc from Mongo from a known user id, this is a bit overkill. On the other hand, if you pull it off, you save yourself a lot of coding to craft the response expected in the FCC test.

UserModel.find()                   // find all users
         .skip(100)                // skip the first 100 items
         .limit(10)                // limit to 10 items
         .sort({firstName: 1}      // sort ascending by firstName
         .select({firstName: true} // select firstName only
         .exec()                   // execute the query
         .then(docs => {
            console.log(docs)
          })
         .catch(err => {
            console.error(err)
          })

I also recommend watching the tutorial in FCC’s YouTube channel, by the same person who authored the article.

https://youtu.be/o3ka5fYysBM

Good luck!

Hey!

Thank you very much!
I did it!!!

This is my filter solution:


// Check if there is a limit in query
      if (req.query.limit) {
        data.exercises = data.exercises.slice(0, req.query.limit);
      }

      // Check if there is a date filter in query

      if (req.query.from || req.query.to) {
        let fromDate = new Date(0);
        let toDate = new Date();

        if (req.query.from) {
          fromDate = new Date(req.query.from);
        }
        if (req.query.to) {
          toDate = new Date(req.query.to);
        }
        fromDate = fromDate.getTime();
        toDate = toDate.getTime();

        data.exercises = data.exercises.filter((session) => {
          let sessionDate = new Date(session.date).getTime();

          return sessionDate >= fromDate && sessionDate <= toDate;
        });
      }