findById returns empty array

import {Router} from 'express';
import { sample_exercises, sample_tags } from '../data';
import expressAsyncHandler from 'express-async-handler';
import { ExerciseModel } from '../models/excersise.model';

const router = Router();

//api for seeding the db
//http://localhost:5000/api/exercises/seed
router.get("/seed", expressAsyncHandler(
    async (req, res) => {
        //count variable to see if db has items
        const exerciseCount = await ExerciseModel.countDocuments();
        if(exerciseCount > 0 ){
            res.send("Already seeded!");
            return;
        }

        //otherwise create all the exercises in the db
        await ExerciseModel.create(sample_exercises);
        res.send("Seed is done!");
    }
));

//using an async function directly results in inconsistent behavior
//hence the usage of express-async-handler
router.get("/", expressAsyncHandler(
    async (req, res) => {
        //calling find() without a parameter gets all the items from the db
        const exercises = await ExerciseModel.find();
        res.send(exercises);
    }
));

router.get("/search/:searchTerm", expressAsyncHandler(
    async (req, res) => {
        //because we're searching through the db, we have to use
        //regex per mongodb standards
        //regex i to make the searchTerm case insensitive 
        const searchRegex = new RegExp(req.params.searchTerm, 'i');
        //$regex: is the operator for regex's
        const exercises = await ExerciseModel.find({name: {$regex:searchRegex}});
        // const searchTerm = req.params.searchTerm;
        // const exercises = sample_exercises
        // .filter(exercise => exercise.name.toLowerCase()
        // .includes(searchTerm.toLowerCase()));
        res.send(exercises);
    })
);

router.get("/:tagName", (req, res) =>{
    const tagName = req.params.tagName;
    const exercises = sample_exercises
    .filter(exercise => exercise.targetgroup.includes(tagName));
    res.send(exercises);
});

// router.get("/:tagName", expressAsyncHandler(
//     async (req, res) => {
//         const exercises = await ExerciseModel.find({tags: req.params.tagName})
//         res.send(exercises);
//       }
// ))

router.get("/:exerciseId", expressAsyncHandler(
    async (req, res) => {
        const exercise = await ExerciseModel.findById(req.params.exerciseId);
        //const exercise = await ExerciseModel.find({_id: req.params.exerciseId})
        res.send(exercise);
    })
);

// router.get("/:exerciseId", (req, res) => {
//     const exerciseId = req.params.exerciseId;
//     const exercise = sample_exercises.find(exercise => exercise.id == exerciseId);
//     res.send(exercise);
// });

export default router;

The get exerciseId is the only one that is giving me trouble, it some how only returns an empty array.
I’ve listed some more of my code for further insight.

import { Schema, model } from "mongoose";

export interface User {
  id: string;
  email: string;
  //we don't save token in the db, hence the pw
  password: string;
  name: string;
  address: string;
  isAdmin: boolean;
}

export const UserSchema = new Schema<User>(
    {
        name: {type: String, required: true},
        email: {type: String, required: true, unique: true},
        password: {type: String, required: true},
        address: {type: String, required: true},
        isAdmin: {type: Boolean, required: true},
    },
    {
        timestamps: true,
        toJSON:{
            virtuals: true
        },
        toObject:{
            virtuals:true
        }
    }
);

export const UserModel = model<User>('user', UserSchema);

Model looks like this

import dotenv from 'dotenv';
dotenv.config();
// for things like process.env.MONGO_URI

import express from "express";
import cors from "cors";
import exerciseRouter from './routers/exercise.router';
import userRouter from './routers/user.router';
import { dbConnect } from './configs/database.config';
import tagRouter from './routers/tag.router';
//each time we start the server, it will try to connect to the db
dbConnect();

const port = 5000;

const app = express();

app.use(express.json());
//use cors so that the credentials are the same
//i.e. use the same localhost so it's userfriendly (not only for developers)
app.use(cors({
    credentials:true,
    origin:["http://localhost:4200"]
}));

app.use("/api/exercises", exerciseRouter);
app.use("/api/users", userRouter);
app.use("/api/tags", tagRouter);

app.listen(port, () => {
    console.log("Website served on http://localhost:" + port);
});

Server looks like this

export const sample_exercises: any[] = [
  {
    id:1,
    name: 'Benchpress',
    description: 'It involves lying on a bench and pressing weight upward using either a barbell or a pair of dumbbells. During a bench press, you lower the weight down to chest level and then press upwards while extending your arm',
    targetgroup: ['mid-chest', 'lower-chest', 'triceps']
  },
  {
    id:2,
    name: 'Pull up',
    description: 'A pull-up is an upper-body exercise that involves hanging from a pull-up bar by your hands with your palms facing away from you, and lifting your entire body up with your arm and back muscles until your chest touches the bar. The pull-up movement uses multiple muscles at once, making it a compound exercise.',
    targetgroup: ['lats', 'traps']
  },
  {
    id:3,
    name: 'Squat',
    description: 'Start with your body weight as you dial in your form. After you get used to it, begin to incorporate the dumbbells. Push your butt back as you squat down to keep the pressure off your knees.',
    targetgroup: ['upper-legs', 'core']
  },
  {
    id:4,
    name: 'Chin up',
    description: 'An exercise in which one hangs by the hands from a support (such as a horizontal bar) and pulls oneself up until the chin is level with the support. specifically : such an exercise done with the palms facing inward compare pull-up.',
    targetgroup: ['lats', 'biceps']
  },
  {
    id:5,
    name: 'Incline benchpress',
    description: 'It involves lying on an incline bench and pressing weight upward using either a barbell or a pair of dumbbells. During a bench press, you lower the weight down to chest level and then press upwards while extending your arm',
    targetgroup: ['upper-chest', 'triceps']
  },
  {
    id:6,
    name: 'Seated twisting dumbell curls',
    description: 'Sit on a bench, hold two dumbbells at your sides with palms facing each other. Use your bicep to curl the dumbbells up to your shoulders, twisting your palms to face your chest as you lift them. Slowly lower the dumbbells back down to your side and repeat.',
    targetgroup: ['biceps', 'forearm']
  },
  {
    id:7,
    name: 'Dips',
    description: 'Perform the dips with your hands behind your back on a chair or bench. Start with your feet on the ground. As you become stronger, place your feet up on another chair to add resistance.',
    targetgroup: ['biceps', 'front-delt', 'chest']
  },
  {
    id:7,
    name: 'Shoulder press',
    description: 'You can perform these either seated or standing. Hold the dumbbells at shoulder level and press them high over your head. Perform the same movement if using bands.',
    targetgroup: ['triceps','front-delt', 'chest']
  },
  {
    id:8,
    name: 'Plank',
    description: 'Get into a push-up position on your elbows instead of your hands, keep your body straight and hold the position for 30 seconds for each round. Rest 15 seconds and then perform another rep. Perform five reps.',
    targetgroup: ['core']
  },
]

export const sample_tags:any[] = [
  {name: "mid-chest"},
  {name: "lower-chest"},
  {name: "triceps"},
  {name: "lats"},
  {name: "biceps"},
  {name: "forearm"},
  {name: "traps"},
  {name: "upper-legs"},
  {name: "front-delt"},
  {name: "core"},
]

export const sample_users:any[] = [
  {
    name: "John Hoe",
    email: "john@gmail.com",
    password: "encrypted123",
    address: "Chiraq",
    isAdmin: true,
  },
  {
    name: "Jane Dough",
    email: "jane@gmail.com",
    password: "secured456",
    address: "Bagdad",
    isAdmin: false,
  },
]

Data looks like this, it’s all seeded inside mongodb

const BASE_URL = 'http://localhost:5000';

export const EXERCISES_URL = BASE_URL + '/api/exercises';
export const EXERCISES_TAGS_URL = EXERCISES_URL + '/tags';
export const EXERCISES_BY_SEARCH_URL = EXERCISES_URL + '/search/';
export const EXERCISES_BY_ID_URL = EXERCISES_URL + '/';

export const TAGS_URL = BASE_URL + '/api/tags';
export const TAGS_BY_NAME = TAGS_URL + '/';

export const USER_LOGIN_URL = BASE_URL + '/api/users/login';
export const USER_REGISTER_URL = BASE_URL + '/api/users/register';

And here are the URL’s

have you tried using “findById” with ({_id: req,params.id})?

or you can also look into "findOne({_id: req,params.id}), see if that solves it, happy learning :slight_smile:

Yes, both of them unfortunately still return an empty array.

The weird thing is, it doesn’t matter what I put in the body. It gives an empty array regardless

Log the route inputs (i.e. the data you think the route is getting) to see if it really is what you think the route is getting. Additionally, find() all the records and log that to make sure the records really are there. Or, you may try to add an exec() on the end of the find() to get a better error if there is one.

Strangely console log also doesn’t work on the findById() route. It works on the other routes, like the find() route. This route gets all the objects, including the nested arrays. It’s connected to the MongoDB Atlas backend and works properly. I tested it by deleting some objects and it returned the updated amount. The exec() method doesn’t execute anything (including the working routes), but that doesn’t really matter since I use Postman to test the API.

For more context, this is how a document entry looks like in MongoDB:

_id
63970a9a9639fc77767361a4
name
"Benchpress"
description
"It involves lying on a bench and pressing weight upward using either a…"

targetgroup
Array
0
"mid-chest"
1
"lower-chest"
2
"triceps"
createdAt
2022-12-12T11:03:54.482+00:00
updatedAt
2022-12-12T11:03:54.482+00:00
__v
0

what does this show if you console log that?

If you can’t log anything (try logging the route name so there’s no lookup) from the route you’re trying to debug, then you’re not hitting the route. If you can’t log the route inputs, but you can log the route name, then the inputs are not reaching the route. Try logging something simple like the route name and run your tests to see which routes are actually running during the tests, then log all the route inputs and responses.

Or intentionally misuse the findById() to make it raise an error and you should see the error on the server console to determine if it is being executed.

What do you mean by lookup and logging the route name? I can’t log anything of that route, not even a static “hello”. Can’t really raise an error either, it always returns undefined. Logging the other routers works fine, but they also function properly

If you can’t log the route name from the route while the server is running and you are trying to hit the route, then the route is not being hit.

Run whatever test you are running to test the route in question with logging from all the routes and see what, if any logging output you get. If none, it’s missing all the routes. If it’s something, then you know which route is running when you think your running the route in question.

Lookup is whatever your find function is. Logging the route name is console.log('GET exercise'); or similar.

Yeah the route is most likely not being executed. All the other routes are working, except the findById(). Logging doesn’t work at all on that route, so that’s out of the question. I’ve been stuck for more than a week on this matter. I think I’m just going to make a new server that uses the NestJS framework, I wanted to try that out anyways. Regardless, thanks for trying to help me out on this matter!

can you tell what these two routes would result in?

  • “/:someId/profile”
  • “/profile/:someId”

im asking cause its “most likely” route that you are using probably going to another controller/router function, which you are not considering looking into…either way good luck and happy learning :slight_smile: