API and backend - exercise tracker - can't pass last test

Hi Folks,

I can’t figure out whats the problem with the last test is. When I test it in the browser it filters the exercises correctly. When I log the params, that comes from the test ,to the console they are undefined.

Would be great f somebody has an idea whats wrong.

Greetings :slightly_smiling_face:
Anton

Project link

solution: https://replit.com/@antono91/project-exercisetracker

Browser information:

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36

Challenge: Exercise Tracker

Link to the challenge:

Log the output response (with your logging included) and you’ll see:

{ _id: '12', from: undefined, to: undefined, limit: undefined }
{
  username: 'fcc_test_16434159457',
  count: 2,
  _id: '12',
  log: [
    { description: 'test', duration: 60, date: 'Mon Jan 01 1990' },
    { description: 'test', duration: 60, date: 'Tue Jan 02 1990' }
  ]
}
{ _id: '12', from: undefined, to: undefined, limit: undefined }
{
  username: 'fcc_test_16434159457',
  count: 2,
  _id: '12',
  log: [
    { description: 'test', duration: 60, date: 'Mon Jan 01 1990' },
    { description: 'test', duration: 60, date: 'Tue Jan 02 1990' }
  ]
}

So, there is no filtering. It’s because the route doesn’t know the filter parameters:

{ _id: '12', from: undefined, to: undefined, limit: undefined }

The spec here could be clearer:

You can add from, to and limit parameters to a GET /api/users/:_id/logs request to retrieve part of the log of any user.

Since those parameters are not included in the enpoint, they are query parameters and not route parameters. Logging the input:

req.body: {}
req.params: {"_id":"12"}
req.query: {"from":"1989-12-31","to":"1990-01-03"}

Your endpoint

app.get('/api/users/:_id/logs/:from?/:to?/:limit?', (req, res) => {

is looking in req.params for route parameters.

1 Like

Thank you very much. That helps a lot.

I have same issue here, and I already made a handler for the req.query if it’s undefined… but still, i can’t pass the last test… here’s my code

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

app.use(express.urlencoded({ extended: true }))
// MongoDB Database
// mongoose.connect()

const Exercise = mongoose.model('Exercise', {
  username: {
    type: String,
    required: true
  },
  log: [{
    description: String,
    duration: Number,
    date: String,
    _id: false
  }]
})

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

  res.setHeader("Access-Control-Allow-Origin", "*")

  const users = await Exercise.find({}, ['username', '__v'])
  res.json(users)
})

app.get('/api/users/:_id/logs', async (req, res) => {

  res.setHeader("Access-Control-Allow-Origin", "*")

  let { from, to, limit } = req.query

  console.log(from, to, limit)

  let fixLimit = limit == undefined ? 1000 : parseInt(limit)
  let fixFrom = new Date(from) == 'Invalid Date' ? new Date(0) : new Date(from)
  let fixTo = new Date(to) == 'Invalid Date' ? new Date() : new Date(to)

  const user = await Exercise.findById(req.params._id)
  if (user == null) return res.json({ error: 'Cannot find the user' })

  const result = { ...user._doc }
  delete result.__v

  const filtered = result.log.filter((element, index) => (index < fixLimit) && (new Date(element.date) >= fixFrom) && (new Date(element.date) <= fixTo))

  result.log = filtered

  if (from != undefined) result.from = new Date(from).toDateString()
  if (to != undefined) result.to = new Date(to).toDateString()

  let count = result.log.length
  result.count = count

  console.log(result)

  // res.json({
  //   _id: result._id,
  //   username: result.username,
  //   from: result.from,
  //   to: result.to,
  //   count: result.log.length,
  //   log: result.log
  // })

  res.json(result)
})

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

  res.setHeader("Access-Control-Allow-Origin", "*")

  const username = await req.body.username
  const test = await Exercise.findOne({ username })

  if (test != null) { console.log('Name already taken') }
  else {
    // Create User
    const user = { username: username }

    const wait = await Exercise.insertMany(user)
    console.log('saved')
  }

  const result = await Exercise.findOne({ username: username })

  res.json({
    username: result.username,
    _id: result._id
  })

})

app.post('/api/users/:_id/exercises', async (req, res) => {

  res.setHeader("Access-Control-Allow-Origin", "*")

  const id = req.params._id
  const user = await Exercise.findById(id)

  let d = new Date(req.body.date) == 'Invalid Date' ? new Date() : new Date(req.body.date)

  d = d.toDateString()

  const input = {
    description: req.body.description,
    duration: Number(req.body.duration),
    date: d
  }

  user.log.push(input)

  const wait = await Exercise.findByIdAndUpdate(id, user)

  res.json({
    username: user.username,
    description: req.body.description,
    duration: parseInt(req.body.duration),
    date: d,
    _id: user._id
  })
})


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

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

Ensure that you save the date without the time before saving to logs;

let d = new Date(req.body.date) == ‘Invalid Date’ ? new Date() : new Date(req.body.date)

d.setHours(0, 0, 0, 0)

d = d.toDateString();

Also for filtering the dates at “/api/users/:_id/logs”

let fixFrom = new Date(from) == ‘Invalid Date’ ? new Date(0) : new Date(from)
fixFrom .setHours(0, 0, 0, 0);
fixFrom = fixFrom .valueOf();

let fixTo= new Date(to) == ‘Invalid Date’ ? new Date(0) : new Date(to)
fixTo.setHours(0, 0, 0, 0);
fixTo= fixTo.valueOf();

const filtered = result.log.filter((element, index) => (index < fixLimit) && (new Date(element.date).valueOf() >= fixFrom) && (new Date(element.date).valueOf() <= fixTo))

This should work if you handle all occurences on your codes, this way you are not considering the time and just focussed on the dates

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