1

I'm stuck with that request already. I'm trying to send FormData to NodeJS server but all I got in backend when I console.log the req.body is empty object. I checked the FormData keys/values and it's all good.

Here is my POST request in frontend:

const createProduct = (e: any) => {
        e.preventDefault();

        const data = new FormData()

        data.append("name", name)
        data.append("description", description)
        data.append("price", price)
        for (const colorAndImage of colorsAndImages) {
            data.append('images', colorAndImage.images[1]);
            data.append('colors', colorAndImage.colors);
        }
        data.append("type", type)

        for (var pair of data.entries()) {
            console.log(pair[0]+ ', ' + pair[1]); // the keys/values are correct
        }

        fetch('http://localhost:4000/products/create', {
            method: 'POST',
            body: data
        })
        .then(response => {
            if (response.status === 201) {
                setName('')
                setDescription('')
                setPrice('')
                setType('')
            } else if (response.status === 500) {
                console.log('error');
            }
        })
        .catch(error => console.log(error));
    }

And my controller in backend:

productController.post('/create', async (req: Request, res: Response) => {
    console.log(req.body)
    try {
        const data = {
            name: req.body.name,
            description: req.body.description,
            price: req.body.price,
            colors: req.body.colors,
            images: req.body.images,
            type: req.body.type,
            likes: req.body.likes
        }
        let product = await create(data)
        res.status(201).json(product)
    } catch (error) {
        console.log(error);
        //res.status(500).json({error: error})
    }
})

Even that I obviously send some data, the req.body is an empty object and I got that error:

Error: Product validation failed: name: Path 'name' is required., description: Path 'description' is required., price: Path 'price' is required., type: Path 'type' is required.

at ValidationError.inspect

UPDATE

My express config:

import express, { Application } from 'express';
import cookieParser from 'cookie-parser';
import cors from 'cors';
import auth from '../middlewares/auth';

const corsConfig: cors.CorsOptions = {
    credentials: true,
    origin: ['http://localhost:3000', 'http://localhost:2000']
}

export default function (app: Application) {
    app.use(cors(corsConfig))
    
    app.use(cookieParser());

    app.use(express.urlencoded({ extended: false }));
    app.use(express.json())

    app.use(auth())
}

And root server:

import express, { Application } from "express";
import routes from './routes'
import config from './config/config'
import mongooseConfig from './config/mongoose'
import expressConfig from './config/express'

const app: Application = express()

expressConfig(app);
mongooseConfig();

app.use(express.json())
app.use(routes)

app.listen(config.PORT, () => console.log(`Server is listening on port ${config.PORT}`))

Routes file:

import { Router } from "express";
import authController from "./controllers/authController";
import productController from "./controllers/productController";

const routes = Router()

routes.use('/auth', authController)
routes.use('/products', productController)

export default routes;
Yoan Ivanov
  • 19
  • 1
  • 7

1 Answers1

0

Maybe you can just submit it as JSON instead of Form data, this works always :smile:

const createProduct = (e: any) => {
        e.preventDefault();

        const data = {
          "name": name,
          "description": description,
          "price": price,
          "colorsAndImages": colorsAndImages,
          "type": type,
        };
        // Please check mappings as I just transferred what you had :smile:

        fetch('http://localhost:4000/products/create', {
            method: 'POST',
            body: JSON.stringify(data),
        })
        .then(response => {
            if (response.status === 201) {
                setName('')
                setDescription('')
                setPrice('')
                setType('')
            } else if (response.status === 500) {
                console.log('error');
            }
        })
        .catch(error => console.log(error));
    }

  • Sure, but can I send image as File in JSON ? Cuz I have input type=file, and that's why I use FormData – Yoan Ivanov Feb 03 '22 at 13:29
  • @YoanIvanov, in that case, I can suggest you to try and use a lib called `multer` here's an article that can help you out with the usage of files. https://stackabuse.com/handling-file-uploads-in-node-js-with-expres-and-multer https://www.npmjs.com/package/multer – Larry Bekchyan Feb 03 '22 at 17:23
  • I know that I need multer but the question is why I can't send data to the backend. Why the req.body Is an empty object – Yoan Ivanov Feb 03 '22 at 19:43
  • I dig more into the code yours, so I think the solution for you will be to use `body-parser` in your express configs and move that to the root server file: here's a topic which can help you more: https://stackoverflow.com/questions/24543847/req-body-empty-on-posts – Larry Bekchyan Feb 04 '22 at 05:48