question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

How to upload file with additional form data

See original GitHub issue

I’m submitting a…


[ ] Regression 
[ ] Bug report
[ ] Feature request
[ X ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

I’m using nestjs/swagger and trying to figure out a way to upload a file and also pass additional form data along with the image.

I’m using this to upload the image, and it works fine.

  @UseInterceptors(FileInterceptor('file'))
  @ApiConsumes('multipart/form-data')
  @ApiImplicitFile({ name: 'file', required: true })
  uploadFile(@UploadedFile() file) {
    console.log('got upload');
    console.log('...file', file);
  }

However, I’d like to include some meta data about my file as form data. I tried using @Body(), but that expects a json payload, and the upload requires multipart/form-data.

  @UseInterceptors(FileInterceptor('file'))
  @ApiConsumes('multipart/form-data')
  @ApiImplicitFile({ name: 'file', required: true })
  uploadFile(@UploadedFile() file, @Body() body: MyDto) {
    console.log('got upload');
    console.log('...file', file);
    console.log('...body', body);
  }

I also tried ApiImplicitBody, but couldn’t seem to get it to work. I’m just guessing because I seem to be deep in undocumented territory.

What is the correct way to:

  • Access other properties of the multi-part form (beyond the file)
  • Define that as part of the swagger definition with the swagger decorators

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:16 (2 by maintainers)

github_iconTop GitHub Comments

8reactions
mwanagocommented, Nov 13, 2018

I experience a similar problem. The file upload does work for me using multipart/form-data, and I am successfully sending additional properties with it:

@Post()
@UseInterceptors(FileInterceptor('file'))
@ApiConsumes('multipart/form-data')
@ApiImplicitFile({ name: 'file', required: true })
async uploadModel(@UploadedFile() file, @Body() modelData: CreateModelDto) {
  // (...)
}

All additional properties are passed to the modelData when sending a proper POST request from the application. The issue is that swagger does not understand it and the “Try it out” does not work. It sends just the file without any additional data.

screenshot from 2018-11-13 12-53-01 screenshot from 2018-11-13 12-53-24

6reactions
concoc116commented, Oct 2, 2019

i have been reading on @nestjs/swagger version 3.1.0 and it no support additional form data, if you want genarate document for this you need to write a custom decorator like this.

api-implicit-form-data.decorator.ts

import { createParamDecorator } from '@nestjs/swagger/dist/decorators/helpers';
import { isNil } from 'lodash';

const initialMetadata = {
    name: '',
    required: true,
};

export const ApiImplicitFormData = (metadata: {
    name: string;
    description?: string;
    required?: boolean;
    type: any;
}): MethodDecorator => {
    const param = {
        name: isNil(metadata.name) ? initialMetadata.name : metadata.name,
        in: 'formData',
        description: metadata.description || '',
        required: metadata.required || false,
        type: metadata.type,
    };
    return createParamDecorator(param, initialMetadata);
};

and using it ad controller function like this: test.controller.ts

@ApiOperation({ title: 'Upload Photo Campaign' })
   @ApiConsumes('multipart/form-data')
   @ApiImplicitFormData({ name: 'imageData', required: true, type: 'file' })
   @ApiImplicitFormData({ name: 'imageInfo', required: true, type: String })
   @ApiImplicitFormData({ name: 'campaignId', required: true, type: String })
   doPhotoCampaignUpload(
       @Req() req: Request,
       @Res() res: Response,
       @UploadedFile() file,
       @Body() uploadInfo,
   ) {
       try {
           Logger.log(file);
           Logger.log(uploadInfo);
            return res.status(HttpStatus.OK).json({
                  status: 200,
                  data: 'On contructing',
             });
       } catch (error) {
           return res.status(HttpStatus.OK).json({
               status: -999,
               data: 'error',
           });
       }
   }
}

i tested on my project, and it working fine hope it help.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to upload single or multiple files the easy way with ...
We'll see examples of using FormData with Ajax, Angular 7, Ionic and React. ... Next, create the index.js file and add following code:...
Read more >
Using FormData Objects - Web APIs | MDN
The FormData object lets you compile a set of key/value pairs to send using XMLHttpRequest . It is primarily intended for use in...
Read more >
How to Multipart File Upload Using FormData with HTML | refine
In this guide, we will look at how we can upload a file from HTML form data to a server with the multipart-upload...
Read more >
How to use FormData for AJAX file upload? - Stack Overflow
var formData = new FormData($('#upload_form')[0]); formData.append('tax_file', $('input[type=file]')[0].files ...
Read more >
How to upload files with FormData using JavaScript
A quick guide to learn how to upload single as well as multiple files with FormData using JavaScript.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found