Search code examples
node.jsreactjsmongodbexpresspostman

Why do I get an empty array?


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


Solution

  • 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);