I have below the backend routes, models and controllers for news. Here, GET method, PUT method, PATCH method and DELETE method works fine except GET news By Id. Whenever I call "getNewsById" method Postman shows me an empty array. I have "newsflashes" collection created in MongoDB and some other collections like "houses", "users", etc. When I call "getHousesById" and "getUsersById" methods, they work fine. So I have the issue only with "getNewsById" which gives me an empty array. I have been spending 3 long days to find this issue, but could not. Please I need your help.
Models/News.js
import mongoose from "mongoose";
const NewsFlashSchema = new mongoose.Schema(
{
title: {
type: String,
required: true,
},
month: {
type: String,
required: true,
},
year: {
type: Number,
required: true,
},
description: {
type: String,
},
documentUrl: {
type: String,
},
},
{ timestamps: true }
);
const NewsFlash = mongoose.model("NewsFlash", NewsFlashSchema);
export default NewsFlash;
Routes/management.js
import express from "express";
import {
getNewsByMonth,
getNewsById,
updateNews,
deleteNews,
saveNews,
saveNewsById,
getNews,
} from "../controllers/management.js";
const router = express.Router();
router.get("/newsflashes", getNews);
router.get("/newsflashes/:month", getNewsByMonth);
router.get("/newsflashes/:id", getNewsById);
router.post("/newsflashes", saveNews);
router.post("/newsflashes/:id", saveNewsById);
router.patch("/newsflashes/:id", updateNews);
router.delete("/newsflashes/:id", deleteNews);
export default router;
Controllers/management.js
import NewsFlash from "../models/News.js";
// get all newsflashes
export const getNews = async (req, res) => {
try {
const newsflashes = await NewsFlash.find();
res.status(200).json(newsflashes);
} catch (error) {
res.status(404).json({ message: error.message });
}
};
// get newsflashes by id
export const getNewsById = async (req, res) => {
try {
const newsflashes = await NewsFlash.findById(req.params.id);
res.json(newsflashes);
} catch (error) {
res.status(404).json({ message: error.message });
}
};
// get newsflashes by month
export const getNewsByMonth = async (req, res) => {
const month = req.params.month;
try {
const newsflashes = await NewsFlash.find({ month });
res.status(200).json(newsflashes);
} catch (err) {
res.status(500).json({ message: "Failed to retrieve newsflashes" });
}
};
// add newsflashes
export const saveNews = async (req, res) => {
const newsflashes = new NewsFlash(req.body);
try {
const insertedNews = await newsflashes.save();
res.status(201).json(insertedNews);
} catch (error) {
res.status(400).json({ message: error.message });
}
};
// add newsflashes by id
export const saveNewsById = async (req, res) => {
const newsflashes = new NewsFlash(req.body);
try {
const insertedNews = await newsflashes.save();
res.status(201).json(insertedNews);
} catch (error) {
res.status(400).json({ message: error.message });
}
};
//update newsflashes
export const updateNews = async (req, res) => {
try {
const updatedNews = await NewsFlash.updateOne(
{ _id: req.params.id },
{ $set: req.body }
);
res.status(200).json(updatedNews);
} catch (error) {
res.status(400).json({ message: error.message });
}
};
//delete newsflashes
export const deleteNews = async (req, res) => {
try {
const deletedNews = await NewsFlash.deleteOne({ _id: req.params.id });
res.status(200).json(deletedNews);
} catch (error) {
res.status(400).json({ message: error.message });
}
};
I have attached the screen shot of database collection also.
2
Answers
getNewsById
will not be called because first/newsflashes/:month
satisfies your request.(how should your application know, if the last parameter is a
month
or anid
)you have to make the endpoints more specific.
e.g.:
It looks like the issue you’re facing with the
getNewsById
route is related to the route configuration. Specifically, the order of your route definitions in theRoutes/management.js
file might be causing conflicts with other routes. Express.js evaluates routes in the order they are defined, and since you have a dynamic route parameter for bothgetNewsByMonth
andgetNewsById
Express is treatinggetNewsById
as if it’s trying to match an id parameter in the URL.To fix this issue, you should reorder your routes so that the more specific routes are defined before the more generic ones. Here’s the updated
Routes/management.js
file with the routes reordered:By moving the
getNewsById
route to the top, you ensure that Express correctly matches the/newsflashes/:id
route before considering it as a generic/newsflashes
route. This should resolve the issue where thegetNewsById
route was returning an empty array.