Back End Development and APIs Projects - Exercise Tracker

Tell us what’s happening:
Describe your issue in detail here.

Mongoose has been updated to use async functions and removed callbacks, it’s been quite the struggle to get a grip over the new method since i was accustomed to using callbacks, however
1- my response for the post " is just fine but it won’t accept it even though they’re identical
2- I’m having trouble saving the updated code with the tests as it keeps giving null error but it saves perfectly fine when tested on replit
3- i had to improvise over problem 2 so i queried for the username because it was returned null in the update
4- when i query the database to test on my replit it gives an error for the items like the logs i called to be null "even though it’s been saved "
5- i downgraded mongoose to use callbacks and still doesn’t read the documents
There’s my code
P.S “i added an if statement to check if the doc is null so i could prevent the error but still the tests won’t pass”

`const express = require('express')
const app = express()
const cors = require('cors')
require('dotenv').config()
const bodyParser = require('body-parser')
const mongoose = require('mongoose')
let uri = "mongodb+srv://yasser:" + process.env.PASS + "@cluster0.tuyrtvl.mongodb.net/?retryWrites=true&w=majority"
mongoose.connect(uri, { useNewUrlParser: true, useUnifiedTopology: true });

app.use(cors())
app.use(express.static('public'))
app.use(bodyParser.urlencoded({ extended: false }))

let excerciseSchema = new mongoose.Schema({
  description: { type: String, required: true },
  duration: { type: Number, required: true }
  ,
  date: Date
})

let userSchema = new mongoose.Schema({
  username: { type: String, required: true },
  log: [excerciseSchema]
});
let Excercise = mongoose.model('Excercise', excerciseSchema);

let User = mongoose.model('User', userSchema);




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

app.post("/api/users", (req, res) => {

  let newUser = new User({ username: req.body.username })

  newUser.save();

  res.send({ 'username': newUser.username, '_id': newUser.id })


})

app.get("/api/users", async (req, res) => {

  let list = await User.find({});
  
   console.log(list)
  res.send(list)

})

app.post("/api/users/:_id/exercises", async (req, res) => {
  let id = req.body[':_id'];
  let newExcercise = new Excercise({
    description: req.body.description,
    duration: req.body.duration,
    date: req.body.date
  })
  if (newExcercise.date === '' || newExcercise.date === 'Invalid Date' || newExcercise.date === null) {
    newExcercise.date =  new Date().toISOString().substring(0,10);
  }
const excercise = await newExcercise.save()

  user = await User.findOne({username: {'$regex': 'fcc'}}).then((data)=>{return data.username})
  
  const doc = await User.findByIdAndUpdate(id, {$push: { log: newExcercise } }).then(( update)=>{
  let response = {}
    response['_id'] = id
    response['username'] = user
    response['date'] = new Date(newExcercise.date).toDateString()
    response['duration'] = parseInt(newExcercise.duration)
    response['description'] = newExcercise.description
    if(update != null){
      update.save()
    }
    res.json(response)
    
  })

 



})
app.get("/api/users/:_id/logs", (req,res)=>{
 let id = req.params[':_id'];

let logs =  User.findById(id,(error,data)=>{
  if(error){
    console.log(error)
  }
  else{
    if(data != null){
      res.send(data)
    }
    
  }
})
let counts =  User.findById(id,(error,data)=>{
  if(error){
    console.log(error)
  }
  else{
    if(data != null){
      
      res.send(data.log.length)
    }
    
  }
})

  
})

  








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

Your project link(s)

solution: boilerplate-project-exercisetracker - Replit

Your browser information:

User Agent is: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/110.0

Challenge: Back End Development and APIs Projects - Exercise Tracker

Link to the challenge:

It doesn’t really matter how you handle the async with mongoose as it supports callbacks and async/await. Starting with the POST user route (from replit)

app.post("/api/users", async (req, res) => {
  let newUser = new User({ username: req.body.username })
  newUser.save()
 );

This saves newUser but doesn’t wait for it to finish, which means other tests that depend on the existence of that user data may fail because they may run before the save is finished. Then, it doesn’t send a response and the test fails. While you’re debugging, you need to log your route inputs and outputs, wait for the save to finish, and then return the response:

app.post("/api/users", async (req, res) => {
  // Log route inputs.
  console.log('POST user');
  console.log(`req.body: ${JSON.stringify(req.body)}`);
  console.log(`req.params: ${JSON.stringify(req.params)}`);
  console.log(`req.query: ${JSON.stringify(req.query)}`);

  let newUser = new User({ username: req.body.username })
  // Await the save.
  await newUser.save()
  // Log route outputs.
  console.log(JSON.stringify(newUser));
  // Return a JSON response with the correct fields.
  return res.json(newUser);
});

You’ll need to do stuff like this throughout your code. Logging inputs and responses is critical during debugging.

1 Like

Thank you very mush that helped, i logged my outputs and found out that when i query using findById it returns undefined for the username and the id although they’ve been saved into the database after i checked and i really don’t know what’s happening here
I tried searching but still got no answer to that

I’ve tried codes that work just fine on my repl but still gives the same update error in the response although the results are saved correctly in the database and i have no clue about what’s happening

I’ve changed the entire code and i’ve been trying for 4 days straight to solve that issue
1-stackoverflow said to define the cluster name in schema and did nothing
2- i checked my database and i found everything saved perfectly fine
the problem is with the findById but i still can’t figure it out

There’s the updated code

const express = require('express')
const app = express()
const cors = require('cors')
require('dotenv').config()


const mongoose = require('mongoose')


let uri = "mongodb+srv://yasser:" + process.env.PASS + "@cluster0.tuyrtvl.mongodb.net/fcc-mongodb-and-mongoose?retryWrites=true&w=majority"
mongoose.connect(uri, { useNewUrlParser: true, useUnifiedTopology: true });

const { Schema } = mongoose;
app.use(cors())
app.use(express.static('public'))
app.use(express.urlencoded({ extended: true }))


const ExcerciseSchema = new Schema({
  description: String,
  duration: Number
  ,
  date: Date,
  user_id: String
}, { versionKey: false })

const Excercise = mongoose.model("Excercise", ExcerciseSchema,"cluster0");

const UserSchema = new Schema({
 username: String
}, { versionKey: false });

const User = mongoose.model("User", UserSchema,"cluster0");








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

app.post("/api/users", async (req, res) => {
 console.log(req.body.username)
   const userObj = new User({ username: req.body.username 
                            })
  
 try{
  const user = await userObj.save();
   console.log(user)
   res.json(user)
 }
  catch(err){
    console.log(err)
  }
                                   

})
app.get("/api/users", async (req, res) => {
  const users = await User.find({})
  res.send(users)
})


app.post("/api/users/:_id/exercises", async (req,res)=>{
const id = req.body[':_id']
  console.log(req.body[':_id'])
  console.log(id)
const{description,duration,date} = req.body

try{
  const user = await User.findById(req.body[':_id'])
  if(!user){
    res.send('could not find user')
  }
  else{
    //log user.id
    console.log(user.id)
    const excerciseObj = new Excercise({
    user_id: user.id,
      description,
      duration,
      date: date? new Date(date): new Date()
      
    })
    const exercise = await excerciseObj.save()
    //find the error
    console.log( user.id,
       user.username)
    
    res.json({
      _id: user.id,
      username: user.username,
      description: exercise.description,
      duration: exercise.duration,
      date: new Date(exercise.date).toDateString()
    })
  }
}  
catch(err){
console.log(err)
res.send('there was an error in saving exercises')  
}  
})
const listener = app.listen(process.env.PORT || 3000, () => {
  console.log('Your app is listening on port ' + listener.address().port)
})

It’s really frustrating I’ve searched a lot and found nothing

The responses are sending perfectly fine outputs but when i run the freecodecamp tests they spit undefined id and username when it comes to this part of the code

try{
  const user = await User.findOne({ _id: id })
  if(!user){
    res.send('could not find user')
  }
  else{
    //log user.id
    console.log(user.id)
    const excerciseObj = new Excercise({
    user_id: user.id,
      description,
      duration,
      date: date? new Date(date): new Date()
      
    })
    const exercise = await excerciseObj.save()
    //find the error
    console.log( user.id,
       user.username)
    
    res.json({
      _id: user.id,
      username: user.username,
      description: exercise.description,
      duration: exercise.duration,
      date: new Date(exercise.date).toDateString()
    })
  }
}  
catch(err){
console.log(err)
res.send('there was an error in saving exercises')  
}

Log out req.body in the /api/users/:_id/exercises POST route.

there it is

{
  ':_id': '64402c2fa17b2579cdd31584',
  description: 'jaj',
  duration: '1',
  date: ''
}

// And there's the response
{"_id":"64402c2fa17b2579cdd31584","username":"shs","description":"jaj","duration":1,"date":"Wed Apr 19 2023"}

Did you try submitting the project so the tests run?

req.body does not contain that. It has description, duration, and sometimes date

Use the browser and inspect the network tab when you submit.

Request URL: https://boilerplate-project-exercisetracker.yasserra-fat.repl.co/api/users/6440441ad40ee01d46aad1f1/exercises

Payload: description=test&duration=60&date=1990-01-01

Response: could not find user


i tried submitting and that’s what i get in the logs

{
  username: 'fcc_test_16819355641',
  _id: new ObjectId("64404cccb5dca69e94da1277")
}
{
  username: 'fcc_test_16819355590',
  _id: new ObjectId("64404cccb5dca69e94da1274")
}
fcc_test_16819355657
{
  username: 'fcc_test_16819355657',
  _id: new ObjectId("64404ccdb5dca69e94da127c")
}
undefined
{ description: 'test', duration: '60', date: '1990-01-01' }
undefined
fcc_test_16819355664
{
  username: 'fcc_test_16819355664',
  _id: new ObjectId("64404cceb5dca69e94da127f")
}
undefined
{ description: 'test', duration: '60', date: '1990-01-01' }
undefined
fcc_test_16819355671
{
  username: 'fcc_test_16819355671',
  _id: new ObjectId("64404ccfb5dca69e94da1282")
}
undefined
{ description: 'test', duration: '60' }
undefined
fcc_test_16819355681
{
  username: 'fcc_test_16819355681',
  _id: new ObjectId("64404cd0b5dca69e94da1285")
}
undefined
{ description: 'test', duration: '60' }
undefined
fcc_test_16819355692
{
  username: 'fcc_test_16819355692',
  _id: new ObjectId("64404cd1b5dca69e94da1288")
}
undefined
{ description: 'test', duration: '60' }
undefined
fcc_test_16819355704
{
  username: 'fcc_test_16819355704',
  _id: new ObjectId("64404cd2b5dca69e94da128b")
}
undefined
{ description: 'test', duration: '60' }
undefined
fcc_test_16819355715
{
  username: 'fcc_test_16819355715',
  _id: new ObjectId("64404cd3b5dca69e94da128e")
}
undefined
{ description: 'test', duration: '60' }
undefined
fcc_test_16819355728
{
  username: 'fcc_test_16819355728',
  _id: new ObjectId("64404cd4b5dca69e94da1291")
}
undefined
{ description: 'test', duration: '60' }
undefined
fcc_test_16819355738
{
  username: 'fcc_test_16819355738',
  _id: new ObjectId("64404cd6b5dca69e94da1294")
}
undefined
{ description: 'test', duration: '60' }
undefined
fcc_test_16819355748
{
  username: 'fcc_test_16819355748',
  _id: new ObjectId("64404cd7b5dca69e94da1297")
}
undefined
{ description: 'test', duration: '60', date: '1990-01-01' }
undefined
undefined
{ description: 'test', duration: '60', date: '1990-01-03' }
undefined
fcc_test_16819358271
{
  username: 'fcc_test_16819358271',
  _id: new ObjectId("64404dd4b5dca69e94da129b")
}
fcc_test_16819358285
{
  username: 'fcc_test_16819358285',
  _id: new ObjectId("64404dd4b5dca69e94da129d")
}
fcc_test_16819358295
{
  username: 'fcc_test_16819358295',
  _id: new ObjectId("64404dd5b5dca69e94da12a2")
}
undefined
{ description: 'test', duration: '60', date: '1990-01-01' }
undefined
fcc_test_16819358300
{
  username: 'fcc_test_16819358300',
  _id: new ObjectId("64404dd6b5dca69e94da12a5")
}
undefined
{ description: 'test', duration: '60', date: '1990-01-01' }
undefined
fcc_test_16819358306
{
  username: 'fcc_test_16819358306',
  _id: new ObjectId("64404dd6b5dca69e94da12a8")
}
undefined
{ description: 'test', duration: '60' }
undefined
fcc_test_16819358313
{
  username: 'fcc_test_16819358313',
  _id: new ObjectId("64404dd7b5dca69e94da12ab")
}
undefined
{ description: 'test', duration: '60' }
undefined
fcc_test_16819358321
{
  username: 'fcc_test_16819358321',
  _id: new ObjectId("64404dd8b5dca69e94da12ae")
}
undefined
{ description: 'test', duration: '60' }
undefined
fcc_test_16819358328
{
  username: 'fcc_test_16819358328',
  _id: new ObjectId("64404dd8b5dca69e94da12b1")
}
undefined
{ description: 'test', duration: '60' }
undefined
fcc_test_16819358335
{
  username: 'fcc_test_16819358335',
  _id: new ObjectId("64404dd9b5dca69e94da12b4")
}
undefined
{ description: 'test', duration: '60' }
undefined
fcc_test_16819358342
{
  username: 'fcc_test_16819358342',
  _id: new ObjectId("64404ddab5dca69e94da12b7")
}
undefined
{ description: 'test', duration: '60' }
undefined
fcc_test_16819358349
{
  username: 'fcc_test_16819358349',
  _id: new ObjectId("64404ddbb5dca69e94da12ba")
}
undefined
{ description: 'test', duration: '60' }
undefined
fcc_test_16819358357
{
  username: 'fcc_test_16819358357',
  _id: new ObjectId("64404ddbb5dca69e94da12bd")
}
undefined
{ description: 'test', duration: '60', date: '1990-01-01' }
undefined
undefined
{ description: 'test', duration: '60', date: '1990-01-03' }
undefined
// this is what logs

try{
  const user = await User.findOne({ _id: id })
  if(!user){
    res.send('could not find user')
  }
  else{
    //log user.id
    console.log(user.id)
    const excerciseObj = new Excercise({
    user_id: user.id,
      description,
      duration,
      date: date? new Date(date): new Date()
      
    })
    const exercise = await excerciseObj.save()
    //find the error
    console.log( user.id,
       user.username)
    
    res.json({
      _id: user.id,
      username: user.username,
      description: exercise.description,
      duration: exercise.duration,
      date: new Date(exercise.date).toDateString()
    })
  }
}  
catch(err){
console.log(err)
res.send('there was an error in saving exercises')  
}  
})

This is the log (well one of them), so how would req.body[':_id'] work?

{ description: 'test', duration: '60', date: '1990-01-01' }

You have too many logs and they are all unlabeled. Comment out all the other logs so you can see what is happening. Add this to the before-mentioned POST handler.

console.log('req.body', req.body);
1 Like

Thanks man it’s fixed now!!!
the problem was with using req.body[‘:_id’] and it’s not inside the body

so instead i had to use req.params._id and it worked

const id = req.params._id
const user = await User.findOne({ _id: id})

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.