Please help: Querying objects in a nested array - Mongoose

Hey all,

I am in the process of completing the API and Microservices curriculum and have found a bit of trouble on the exercise tracker.

Everything is fine other than the final three user stories: querying by date.

I have nested the object of each exercise in the log array, as is the case on the example. However, I cannot, for the life of me, figure out how to query the nested objects.

I have checked the mongo db documentation and followed their syntax but to no avail. I understand that formatting of the date object could be the issue so I have tried multiple formats, that didn’t work.

I also realised that it could be an issue with querying a date so attempted to bring all documents with a count greater than 0, again, no avail.

All I seem to get is a blank array every time. The code is as follows:

// init project
const express = require('express');
const mongoose = require('mongoose');
const mongodb = require('mongodb');
const bodyParser = require('body-parser');
const app = express();
// Use bodyparser to get the post body data.
app.use(bodyParser.urlencoded({ extended: false }));
// Make mongoose use createindexes instead of ensureIndexes to prevent depreceation warnings
// This is so the username field can be set to 'unique'.
mongoose.set('useCreateIndex', true);
// Connect to mongoDB using mongoose 
mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true });
// Make the schema for Usernames
const userNameSchema = mongoose.Schema({
  username: {
    type: String,
    unique: true,
    required: true
  },
  count: {
    type: Number,
    required: false
  },
  log: {
    type: Array,
    required: false
  }
});
// Make a model for users
const User = new mongoose.model('User', userNameSchema);
// Handle the post request
app.post('/api/exercise/new-user', ( req, res ) => {
  // Create the new user object
  let newUser = new User({
    username: req.body.username.toLowerCase()
  })
  // Check to see if it already exists
  User.findOne(
    { username: req.body.username.toLowerCase() }, 
    ( err, doc ) => ( err ) ? 
    userCheckHandler( err ) : 
    userCheckHandler( err, doc)
  );
  // Handle the check above
  const userCheckHandler = ( err = null, user = null ) => {
    // Check for an error.
    if( err )
      return console.error( err );
    // Check if username is taken
    if( user )
     return (
       console.log( 'Username taken' ),
       res.json({ error: "Username taken"})
     );
    // Save it to the DB if it isn't.
    newUser.save(( err, doc ) => {
      // Check for error
      if( err )
        return console.error( err );
      // Log that it was saved.
      console.log( `Saved ${doc}`)
      // Return the document which was just saved.
      res.json(doc)
    })
  }
});
// Make a post request for adding exercise
app.post('/api/exercise/add', ( req, res ) => {
  // First check it is a valid username.
  User.findOne(
    { username: req.body.name.toLowerCase() }, 
    ( err, doc ) => ( err ) ? exerciseHandler( err ) : exerciseHandler( err, doc )
  );
  const exerciseHandler = ( err = null, doc = null ) => {
    // Handle errors
    if( err ) 
      return (
        console.error( err ),
        res.json({ error: err })
      );
    if( !doc )
      return (
        console.error( 'Unrecognised username' ),
        res.json({ error: 'Unrecognised username' })
      );
    if( new Date() < new Date( req.body.date ) )
      return (
        console.error( 'Date must be in the past'),
        res.json({ error: 'Date must be in the past' })
      );
    // Create exercise object
    let newExercise = new Object({
      description: req.body.exercise,
      duration: req.body.duration,
      date: new Date(req.body.date).toDateString()
    });
    // Add the new exercise to the log array
    doc.log.push(newExercise);
    // Set the count to match the length of the log
    doc.count = doc.log.length;
    // Save the updated document
    doc.save(( err, upDoc ) => {
      console.log( 'Exercise added!' );
      // Print the updated object to the screen
      res.json( upDoc );
    });
  };
});
// Handle the url encoded requests
app.get('/api/exercise/log', ( req, res ) => {
  // Check to see if any queries have been passed;
  let userId = ( req.query.userId ) ? req.query.userId : null;;
  let from = ( req.query.from ) ? req.query.from : null;
  let to = ( req.query.to ) ? req.query.to : null;
  let limit = ( req.query.limit ) ? req.query.limit : null;
  // Build a blank query object
  let query = {};
  // Handle the passed queries.
  if( userId, from, to, limit ) {
    res.json( req.query );
  } else if( userId, from, to ) {
    res.json( req.query );
  } else if( userId, from ) {
    let query = {
      log: {
        date: {
          $gte: new Date( from ).toDateString()
        }
      }
    };
    User.find( query, ( err, docs ) => {
      return res.json( docs );
    });
  } else if ( userId ) {
    User.findById(req.query.userId, ( err, doc ) => {
      return ( doc ) ? res.json( doc ) : res.json({ error: `No users with the ID: ${req.query.userId}`});
    })
  } else {
    return res.json({ error: "No query detected!" });
  }
});

// http://expressjs.com/en/starter/static-files.html
app.use(express.static('public'));

// http://expressjs.com/en/starter/basic-routing.html
app.get('/', function(request, response) {
  response.sendFile(__dirname + '/views/index.html');
});

// listen for requests :)
const listener = app.listen(process.env.PORT, function() {
  console.log('Your app is listening on port ' + listener.address().port);
});

This has been really bugging me so any help would be massively appreciated.

App can be accessed here: https://ms-fcc-exercise-trac.glitch.me/