Exercise tracker Challenge issue

Hi campers,

I’ve been working on this project at the same time as my URL shortener (Thank you @kevinSmith again) and I am stuck

So, before anything, here is my code

server.js

const express = require('express')
const app = express()
const bodyParser = require('body-parser')
const mongo = require('mongodb').MongoClient;

const cors = require('cors')
const methods = require('./methods')

let db = null;

mongo.connect(process.env.URI, (err, database) => {
  if (err) throw err;
  db = database;
});

app.use(cors())

app.use(bodyParser.urlencoded({extended: false}))
app.use(bodyParser.json())


app.use(express.static('public'))
app.get('/', (req, res) => {
  res.sendFile(__dirname + '/views/index.html')
});

app.post("/api/exercise/new-user", (req, res) => {
  var collection = db.collection('users');
  
  methods.newUserHandler(req, res, collection);
})

app.get("/api/exercise/users", (req, res) => {
  var collection = db.collection('users');
  methods.getUsers(req, res, collection);
})

app.post("/api/exercise/add", (req, res) => {
  var collection = db.collection('users');
  methods.addHandler(req, res, collection);
})

app.get("/api/exercise/log", (req, res) => {
  var collection = db.collection('users');
  methods.getLog(req, res, collection);
})


// Not found middleware
app.use((req, res, next) => {
  return next({status: 404, message: 'not found'})
})

// Error Handling middleware
app.use((err, req, res, next) => {
  let errCode, errMessage

  if (err.errors) {
    // mongoose validation error
    errCode = 400 // bad request
    const keys = Object.keys(err.errors)
    // report the first validation error
    errMessage = err.errors[keys[0]].message
  } else {
    // generic or custom error
    errCode = err.status || 500
    errMessage = err.message || 'Internal Server Error'
  }
  res.status(errCode).type('txt')
    .send(errMessage)
})

const listener = app.listen(process.env.PORT || 3000, () => {
  console.log('Your app is listening on port ' + listener.address().port)
})

package.json

{
  "name": "fcc-exercise-tracker",
  "version": "0.1.0",
  "description": "A REST API project, part of Free Code Camp's curriculum",
  "main": "server.js",
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "express": "^4.16.3",
    "mongoose": "^5.1.4",
    "mongodb": "^3.0.10",
    "body-parser": "^1.18.3",
    "cors": "^2.8.4",
    "shortid": "^2.2.8",
    "chrono-node": "^1.3.5"
  },
  "engines": {
    "node": "6.9.1"
  },
  "repository": {
    "url": "https://gomix.com/#!/project/welcome-project"
  },
  "license": "MIT",
  "keywords": [
    "node",
    "gomix",
    "express"
  ]
}

App is running good.
:checkered_flag::bread: Your app is listening on port 3000

… however, when I try to create username, it is showing me

db.collection is not a function

I have checked online before posting here and from what I was able to see, this is an issue with MongoDB but I was not able to find anywhere the final resolution as to how to resolve this issue so I was just wondering if someone can help me out with this.

Thank you in advance for any assistance.

If I look at the beginning of your app:

const express = require('express')
const app = express()
const bodyParser = require('body-parser')
const mongo = require('mongodb').MongoClient;

const cors = require('cors')
const methods = require('./methods')

let db = null;

mongo.connect(process.env.URI, (err, database) => {
  if (err) throw err;
  db = database;
});
// ...

I see a similar problem to last time. You are trying to access process.env.URI but where is it loaded. Do you have it in a .env file somewhere? How is it going to get into this file? Again, you need require('dotenv').config() somewhere in there before this so those variables in the .env get loaded. Otherwise it is undefined.

I can’t test the code because we are missing some files, but I would make that change and then change the db loading function to

console.log('Attempting to load DB, URI:', process.env.URI);
mongo.connect(process.env.URI, (err, database) => {
  if (err) {
    console.log('Error loading DB:', err)
    throw err;
  } else {
    console.log('Database loaded:', process.env.URI)
    db = database;
  }
});

(Check for errors, I’m just doing this off the top of my head.)

As I said before, if something isn’t working right, start console.log-ing like crazy and figure out where what you think is happening is not happening. This is a basic debugging skill.

Hi @kevinSmith

Question: Where do I put the second part of the code that you have provided me with ?

I just don’t want to mess it up so I figured I would ask before I go into coding.

I just came back from work and I am ready to code so if you can, please, let me know that will be great.

Update on the matter @kevinSmith

So I have commented out code that I have had and I was able to add the code that you have advised me of (Thank you again!) and I am getting this

Attempting to load DB, URI: mongodb://admin:admin1@ds025973.mlab.com:25973/exercise-tracker
5:54 PM
:man_with_gua_pi_mao::frog: Your app is listening on port 3000
5:54 PM
Database loaded: mongodb://admin:admin1@ds025973.mlab.com:25973/exercise-tracker

However, I am still getting the same error when I try creating username.

Do I need to do something with database ? Add users ?

Well, that looks normal, so the next step is to put a console.log in that route handler and find out what db is. Did it get set properly? This is basic debugging, this should be your first step when this happens - if it isn’t what you think it is, find out what it is, and keep checking backwards until you find the problem.

Again, I will say this again, and again, and again - SIMPLIFY!!!

If you can’t figure it out, break it into smaller pieces. Having trouble understanding connecting to the DB, then simplify and try just that.

require('dotenv').config();
const mongo = require('mongodb').MongoClient;

let db = null;

console.log('Attempting to load DB, URI:', process.env.URI);
mongo.connect(process.env.URI, (err, db) => {
  if (err) {
    console.log('Error connecting to DB:', err)
    throw err;
  } else {
    console.log('DB connected:', process.env.URI)
    db = database;
    const testRec = {
      title: 'a test message',
      text: 'Did it work?'
    }
    db.collection('test').insertOne(testRec, (err, res) => {
        if (err) {
          console.log('Error saving data:', err)
          db.close();
          return console.log(err);
        }
        console.log('succeeded storeing record:', res)
        db.close();
      }
    )
  }
});

Simplify until it is small enough to understand and then slowly build up. You don’t learn how to be a chef by cooking a 7 course meal for 20 people on your first day. You learn how to make an omelette. Then you learn how to make bread. Then you learn how to make a nice salad dressing, etc., etc. If you don’t understand the basics, then don’t move on to combining the basics together until you do.

Hi @kevinSmith

So I got the issue with submitting new user working. I was playing around with code and I was able to get it working.

Now, another issue is that it is not letting me add exercised for already registered user.

Here is the code that I have

app.post('/api/exercise/add', (req, res) => {
  const exercise = {
    description: req.body.description,
    duration: req.body.duration,
    date: req.body.date ? req.body.date : new Date()
  }
  
  User.findByIdAndUpdate(req.body.userId, { 
    "$push": { "exercise": exercise } 
  }, { new: true }, (err, doc) => {
    console.log(doc)
    if (err) {
      return res.status(500).send({message: err.message});
    }
  
    res.send(doc);
  });
});

When I try adding exercise for already existing user, it is showing me following error.

{"message":"Cast to ObjectId failed for value \"BoCode\" at path \"_id\" for model \"User\""}

Do you know the old proverb, “give a man a fish and you feed him for a day; teach a man to fish and you feed him for a lifetime”? I feel like I keep trying to teach you to fish and you keep asking me to just give you the fish.

Put console.log statements everywhere. What is req.body coming back as? Log out the *exercise" object and check it out. Check to confirm that that id is in the DB. Read that error message? What is it trying to tell you? Google the phrase mongo Cast to ObjectId failed for value and see what it says.

Debugging and figuring these things out is a huge part of web dev. If you aren’t learning how to do this stuff, you aren’t learning web dev. You will learn soooooooooooooooooooooooooo much more if you try to find it yourself. If you still can’t get it in a few days, check back. But fight for it. This is not a profession for people without drive.

I made such a dumb mistake ; when I was testing it out, I put userID as the actual name of the user instead of the ID that was distributed. That’s why it was not working. It is actually working.

Thank you @kevinSmith for assisting me and giving me a feedback.

I am so sorry if I sound like I am rushing through things but I guess some people are different than others. I learn from my mistakes and I try to not make the same mistake again as I move on to the next project.

No, no, I understand. I admire your enthusiasm. There is nothing wrong with making mistakes - that’s how I learn too. But I’d like to see more of you trying to figure out what was wrong instead of asking us. That is the nuclear option that should be reserved for when other options have been expended.