简体   繁体   中英

why am i not getting post api body inside multer request body in node.js?

I have a node.js based server in which i have addProduct api in which i am receiving an object and image files also.

in my api.route.js file i am doing like this

import { Router } from "express";
import { log, loggedIn } from "./middlewares/index";
import { addProduct, getAllProducts, getProductById, updateProduct, deleteProduct } from "./handlers/product";
const multer = require('multer');
const uploadFolder = 'uploads/';
const fs = require('fs');


var storage = multer.diskStorage({
destination: (req, file, cb) => {
    // console.log(req.res, 'name')
    // console.log(Object.keys(req), 'keys')
    if (fs.existsSync(`uploads/${req.body.categoryName}`)) {
        cb(null, `uploads/${req.body.categoryName}`);
    } else {
        fs.mkdir(`uploads/${req.body.categoryName}`, err => {
            if (err) {
                console.log('err in creating folder', err);
            } else {
                cb(null, `uploads/${req.body.categoryName}`);
            }
         });
       }
     },
      filename: (req, file, cb) => {
       cb(null, file.originalname);
      }
     });

  var upload = multer({
     storage: storage
  })

router.post("/", log, upload.fields([{ name: 'image' }, { name: 'cover_image' }, { name: 'thumbnail_image' }]), addProduct);

And in my product.controller.js i am doing like this

export async function addProduct(req, res) {
let productImages = [];
try {
    let body = parseBody(req)
        // console.log('----body----', body)
    if (body) {
        console.log(req.files, 'files')
        if (req.files['image']) {
            req.files['image'].forEach(item => {
                productImages.push(item.filename)
            })
            body.images = pictures
        }
        if (req.files['cover_image'] && req.files['thumbnail_image']) {
            body.coverImage = req.files['cover_image'][0].filename;
            body.thumnbnailImage = req.files['thumbnail_image'][0].filename;
        }

        let product = await saveProduct(body)
        if (product) {
            generateResponse(product.success, product.message, product.data, res)
        }
    } else {
        generateResponse(false, "Please provide complete info", null, res)
    }
} catch (err) {
    console.log('----------Error---------', err)
    generateResponse(false, 'Error occured, 404 not found!', err, res)
   }
 }

I have angular7 on client-side and have image upload like this in component.html

 <form enctype="multipart/form-data"> <div class="form-group row"> <div class="col-lg-12"> <input type="text" name="name" nbInput fullWidth placeholder="Name" [(ngModel)]="product.name" [ngModelOptions]="{standalone: true}"> </div> </div> <div class="form-group row"> <div class="col-lg-12"> <nb-select [(ngModel)]="product.category" name="category" class="type-select" style="display: initial;" (selectedChange)="getBrands()"> <nb-option value="1">Select Category</nb-option> <nb-option *ngFor="let category of allCategories" value="{{category._id}}">{{category.displayLabel}}</nb-option> </nb-select> </div> </div> <div class="form-group row"> <div class="col-lg-12"> <nb-select [(selected)]="product.brand" name="brand" class="type-select" style="display: initial;"> <nb-option value="1">Select Brand</nb-option> <nb-option *ngFor="let brand of categoryBrands" value="{{brand._id}}">{{brand.name}}</nb-option> </nb-select> </div> </div> <div class="form-group row"> <div class="col-lg-12"> <tag-input [(ngModel)]="selectedSizes" [ngModelOptions]="{standalone: true}" theme='bootstrap' placeholder="Enter sizes" secondaryPlaceholder="Enter sizes"></tag-input> </div> </div> <div class="form-group row"> <div class="col-lg-12"> <tag-input [(ngModel)]="selectedColors" [ngModelOptions]="{standalone: true}" theme='bootstrap' placeholder="Enter colors" secondaryPlaceholder="Enter colors"></tag-input> </div> </div> <div class="form-group row"> <div class="col-lg-12"> <input type="text" name="desc" nbInput fullWidth placeholder="Description" [(ngModel)]="product.description" [ngModelOptions]="{standalone: true}"> </div> </div> <div class="form-group row"> <div class="col-lg-12"> <input type="number" name="price" nbInput fullWidth placeholder="Unit Price" [(ngModel)]="product.price" [ngModelOptions]="{standalone: true}"> </div> </div> <div class="form-group row"> <div class="col-lg-12"> <input type="number" name="quantity" nbInput fullWidth placeholder="Quantity" [(ngModel)]="product.quantity" [ngModelOptions]="{standalone: true}"> </div> </div> <div class="form-group row"> <div class="col-lg-12"> <input type="number" name="discount" nbInput fullWidth placeholder="Discount (Option)" [(ngModel)]="product.discount" [ngModelOptions]="{standalone: true}"> </div> </div> <div class="form-group row"> <div class="col-lg-12"> <div class="custom-file mb-3"> <input type="file" name="thumbnail" class="custom-file-input" id="customFile" (change)="onThumbnailImageChanged($event)" [(ngModel)]="product.thumnbnailImage" [ngModelOptions]="{standalone: true}"> <label class="custom-file-label" id="ti">Select Thubnail Image</label> </div> <p *ngIf="isFileError" style="color:red;font-size:11px">{{fileErrorMsg}}</p> </div> </div> <div class="form-group row"> <div class="col-lg-12"> <div class="custom-file mb-3"> <input type="file" name="cover" class="custom-file-input" id="customFile" (change)="onCoverImageChanged($event)" [(ngModel)]="product.coverImage" [ngModelOptions]="{standalone: true}"> <label class="custom-file-label" id="ci">Select Cover Image</label> </div> <p *ngIf="isFileError" style="color:red;font-size:11px">{{fileErrorMsg}}</p> </div> </div> </form>

The issue which i am facing is that i am receiving object and images files in the product.controller.js in req.body but inside my api.routes.js in multer storage function i am not getting my body object in req.body . Because in my req.body i want to get my object with the help of which i have to construct a path for image uploading. How can i get my body inside multer storage function?

Your'e sending a file with your form using a POST request. You should set enctype="multipart/form-data" as attribute on your form when you're sending file input to your server.

Here you can find the specification

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM