skip to Main Content

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.

enter image description here

2

Answers


  1. getNewsById will not be called because first /newsflashes/:month satisfies your request.

    router.get("/newsflashes/:month", getNewsByMonth);
    router.get("/newsflashes/:id", getNewsById);
    

    (how should your application know, if the last parameter is a month or an id)

    you have to make the endpoints more specific.

    e.g.:

    router.get("/newsflashes/month/:month", getNewsByMonth);
    router.get("/newsflashes/id/:id", getNewsById);
    
    Login or Signup to reply.
  2. 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 the Routes/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 both getNewsByMonth andgetNewsById Express is treating getNewsById 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:

    import express from "express";
    
    import {
      getNewsByMonth,
      getNewsById,
      updateNews,
      deleteNews,
      saveNews,
      saveNewsById,
      getNews,
    } from "../controllers/management.js";
    
    const router = express.Router();
    
    router.get("/newsflashes/:id", getNewsById); // Place this before the generic /newsflashes route
    router.get("/newsflashes/:month", getNewsByMonth);
    router.get("/newsflashes", getNews);
    router.post("/newsflashes", saveNews);
    router.post("/newsflashes/:id", saveNewsById);
    router.patch("/newsflashes/:id", updateNews);
    router.delete("/newsflashes/:id", deleteNews);
    
    export default router;
    

    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 the getNewsById route was returning an empty array.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search