Warm tip: This article is reproduced from serverfault.com, please click

NodeJs Iterate over req.files from swagger array having format type as binary

发布于 2020-11-23 09:11:01

I am using swagger with Node and now stuck at multiple file upload part as i am able to get my files on server using swagger-fileupload-docs document page.

middleware is multer and i use below settings in my server.ts file or in the main file from where execution starts

import 'reflect-metadata';

import bodyParser from 'body-parser';
import cors from 'cors';
import express from 'express';
import bunyanMiddleware from 'express-bunyan-logger';
import fg from 'fast-glob';
import helmet from 'helmet';
import { createConnection } from 'typeorm';
import config from './config';
import ErrorHandler from './middlewares/errorHandler';
import logger from './utils/logger';

async function start(): Promise<void> {
    logger.info('Starting server...');

    await createConnection();

    const app = express();

    // Register middlewares
    const appUrl = new URL(config.app.url);
    app.use(cors({
        origin: config.env === 'production' ? appUrl.origin : '*',
    }));
    app.use(helmet());

    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({extended: true}));
    app.use(bunyanMiddleware({
        logger,
        parseUA: false,
        excludes: ['response-hrtime', 'req-headers', 'res-headers'],
        format: ':incoming :method :url :status-code',
    }));

    // Register routes
    const routes = await fg('./routes/*.(ts|js)', { cwd: __dirname });
    for (const routePath of routes) {
        const { default: router } = await import(routePath);
        if (typeof (router) === 'function') app.use(config.server.basePath, router);
    }

    // Error handler must come last...
    app.use(ErrorHandler);

    // Kick it off!
    app.listen(config.server.port, async () => {
        logger.info({ port: config.server.port }, 'Hey! I\'m listening...');
    });
}

start();


and now in the ROUTE file for product.ts code is given below using multer

import Joi from '@hapi/joi';
import express, { Router } from 'express';
import { ProductStatus, Role, } from '../models/enums';

import { authorize } from '../middlewares/authorize';
import { wrapAsync } from '../utils/asyncHandler';

import { Request, isUserReq } from './interfaces';
import { createBrand, deleteBrand, getAllBrands, updateBrand } from '../services/brand';
import multer from 'multer';
import { createProduct, deleteProduct, getAllProducts, updateProduct } from '../services/product';

const upload = multer({ dest: '/tmp/' })

const router = Router();

router.post('/products', authorize(), upload.array('imagesPath'), wrapAsync(async (req: Request, res: express.Response) => {
   
    var files = req.files;

    const { name, price, status, categoryId, vendorId } = await Joi
        .object({
            name: Joi.string().trim().min(3).max(50).required().label('Name'),
            price: Joi.number().min(1).max(10000).required().label('Price'),
            status: Joi.string().valid(ProductStatus.IN_STOCK, ProductStatus.OUT_OF_STOCK, ProductStatus.RUNNING_LOW).required().label('Status'),
            categoryId: Joi.string().trim().uuid().required().label('Category ID'),
            vendorId: Joi.string().trim().uuid().required().label('Vendor ID'),
            
        })
        .validateAsync(req.body);


But i am not able to iterate over req.files as it is giving below error

enter image description here

and my swagger doc are as follow.

/**
 * @swagger
 * /products:
 *   post:
 *     tags:
 *       - Product
 *     summary: Create a product
 *     consumes:
 *       - multipart/form-data
 *     security:
 *       - JWT: []
 *     requestBody:
 *       required: true
 *       content:
 *         multipart/form-data:
 *           schema:
 *             type: object
 *             properties:
 *               name:
 *                 description: Product name
 *                 type: string
 *               price:
 *                 description: Product price
 *                 type: string
 *               status:
 *                 description: Product status
 *                 type: string
 *                 enum: [OUT_OF_STOCK, IN_STOCK, RUNNING_LOW]
 *               imagesPath:
 *                 description: Product logo 
 *                 type: array
 *                 items:
 *                   type: string 
 *                   format: binary     
 *               categoryId:
 *                 type: string
 *               vendorId:
 *                 type: string
 *     produces:
 *       - multipart/form-data
 *     responses:
 *       200:
 *         description: OK
 *         content:
 *           application/json:
 *             schema:
 *               $ref: '#/components/schemas/Product'
 *             example:
 *               id: 2efa52e2-e9fd-4bd0-88bc-0132b2e837d9
 *               name: Product 1
 *               price: 25
 *               status: IN_STOCK   
 *               imagesPath: ['https://${config.s3.Images}.s3.amazonaws.com/${req.file.originalname}']
 *               categoryId: 2efa52e2-e9fd-4bd0-88bc-0132b2e837d9
 *               vendorId: 4efa52e5-e6fd-4bd0-68bc-0132b2e83ww49
 *       401:
 *         $ref: '#/components/responses/UnauthorizedError'
 *       409:
 *         $ref: '#/components/responses/ConflictError'
 *       500:
 *         $ref: '#/components/responses/InternalError'
 */


OPENAPI POST DEFINATIONS that i am using for my api and using format as binary.

Questioner
Miky
Viewed
0
Chandan 2020-12-05 02:30:07

use typeof req.files to check if its array

if its not array then you can use any of these to convert it to array and then use forEach: Array(req.files).forEach(f => console.log(f))
Array.from(req.files).forEach(f => console.log(f))
[].forEach.call(req.files, console.log)