Home > Software design >  Express, request body is {} in middleware, but has content in controller
Express, request body is {} in middleware, but has content in controller

Time:10-29

Here is my server.js:

  import express from "express";
import mongoose from "mongoose";
import productRouter from "./routers/productRouter.js";
import dotenv from "dotenv";

dotenv.config();

const app = express();
app.use(express.json());
let prof = process.env.PROF;

mongoose.connect(
 `${prof}`
);

// Add headers before the routes are defined
app.use(function (req, res, next) {
  // Website you wish to allow to connect
  res.setHeader("Access-Control-Allow-Origin", "*");

  // Request methods you wish to allow
  res.setHeader(
    "Access-Control-Allow-Methods",
    "GET, POST, OPTIONS, PUT, PATCH, DELETE"
  );

  res.header("Access-Control-Allow-Headers", "Content-Type");
  // Request headers you wish to allow
  // res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');

  // Set to true if you need the website to include cookies in the requests sent
  // to the API (e.g. in case you use sessions)
  res.setHeader("Access-Control-Allow-Credentials", true);

  // Pass to next layer of middleware
  next();
});
/*
app.get("/api/products", (req, res) => {
  res.send(data);
});*/

app.use("/api/products", productRouter);

app.get("/", (req, res) => {
  res.send("Server is ready");
});

const port = process.env.PORT || 5000;
app.listen(port);

Going inside productRouter.js ...

  import express from "express";
import mongoose from "mongoose";
import data from "../data.js";
import Product from "../models/productModel.js";
import { payment } from "./paymentController.js";

const productRouter = express.Router();

productRouter.use("/pay", async (req, res, next) => {
  // dont store cart in db, store it in local storage. On checkout get Id of all items in cart. Then find their prices from the db and charge correctly.
  console.log("middleware ran");
  console.log(req.body);
  const productIdsAndAmounts = req.body.basketItems.items.map((item) => {
    return { id: item.id, amount: item.amount };
  });

  // this works faster (apparently)
  /*
  const objIds = productIds.map((id) => mongoose.Types.ObjectId(id));
  const orderedItems = await Product.find({
    _id: { $in: objIds },
  });
*/
  // this sends more query requests to db
  const orderedItems = await Promise.all(
    productIdsAndAmounts.map((productId) => {
      return Product.findById(productId.id);
    })
  );

  let i = -1;
  let productIdsPricesAmounts = [];
  orderedItems.forEach((item) => {
    i = i   1;
    productIdsPricesAmounts.push({
      id: item.id,
      price: item.price,
      amount: productIdsAndAmounts[i].amount,
    });
  });
  console.log(productIdsPricesAmounts);

  const prices = productIdsPricesAmounts.map((item) => {
    return item.price * item.amount;
  });
  const reducer = (prevValue, currValue) => prevValue   currValue;
  const totalTotalPrice = prices.reduce(reducer);

  console.log(totalTotalPrice);

  req.totalPrice = totalTotalPrice;

  //console.log(orderedItems);
  //console.log(productIdsAndAmounts);

  // console.log(req.body.user); // adres
  next();
});

productRouter.get("/", async (req, res) => {
  const products = await Product.find({});
  res.send(products);
});

productRouter.post("/pay", payment);

export default productRouter;

Now to the paymentController.js:

export const paymentController = async (req, res, next) => { 
console.log(req.body.basketItems)
/* returns contents of the body like expected, i can do whatever i want with it*/ 
}

The behaviour, i can get is: Client sends request to "api/products/pay", i have access to req.body in paymentController.

The behaviour, i want is: Client sends request to "api/products/pay", the request first goes through a middleware where i do some calculations on it, then i forward the new variable to my paymentController. The problem is req.body is {} in middleware productRouter.use(), but available in paymentController

What am I doing wrong ? I'm new to express and i don't exactly know what I'm doing yes. I want to have access to req.body inside productRouter. I'm guessing i set up the middleware wrong or something like that. But I can't see what i did wrong.

CodePudding user response:

Can You Use Router For Example :

user.ts

import express from "express";
let UserRoute = express.Router()
UserRoute.get('/',function (req,res) {
    res.json('Hello World')
})

export { UserRoute }

App.ts

import express from "express";
import cors from "cors";
import {  UserRoute } from "./routes/v1/user"
const http = require('http');
const app = express();
const server = http.createServer(app);
const  PORT : string|number = process.env.PORT || 5000;
app.use(cors());
app.use(express.json());
app.use('/',UserRoute)



//Run Server And Listen To Port
server.listen(PORT,()=>{
    console.log("Server UP")
})

CodePudding user response:

Guess this is your main route where you want to add middleware function right Create a middle were function with name "abc" export from there as name "abc"

Now, here in main route you can use that function as a middleware

productRouter.post("/pay",abc, payment);

here abc is your middleware function

  • Related