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/