Vishal Rana
Vishal Rana

Reputation: 11

file upload not working in react native with multipart form data api nodejs

I am trying to upload image file with react native, by using nodejs multipart api, but the file is not getting sent from the FE. If I console req.files its undefined at server side. Here is my react native code:

       var options = {
           title: 'Select Image',
           storageOptions: {
               skipBackup: true,
               path: 'images'
           }
       };
       ImagePicker.showImagePicker(options, (response) => {
           console.log('Response = ', response);
           if (response.didCancel) {
               console.log('User cancelled image picker');
           } else if (response.error) {
               console.log('ImagePicker Error: ', response.error);
           } else if (response.customButton) {
               console.log('User tapped custom button: ', response.customButton);
           } else {
               console.log('User selected a file form camera or gallery', response);
               const data = new FormData();
               data.append('name', 'avatar');
               data.append('file', {
                   uri: response.uri,
                   type: response.type,
                   name: response.fileName
               });
               const config = {
                   method: 'POST',
                   headers: {
                       'Accept': 'application/json',
                       'Content-Type': 'multipart/form-data',
                   },
                   body: data,
               };
               fetch("http://myapi.com/api/v1/user", config)
                   .then((checkStatusAndGetJSONResponse) => {
                       console.log(checkStatusAndGetJSONResponse);
                   }).catch((err) => { console.log(err) });
           }
       }
       )

and Nodejs code:

const storage = multer.memoryStorage({
    destination:(req, file, callback) => {
        callback(null, '')
    }
});

const upload = multer({ storage: storage }).array('file');
    upload(req,res,(err) => {
        if(err) {
            console.log('ERROR: ',err);
            return res.end("Error uploading file.");
        }else{
            console.log('REQUEST: ',req.files);
        }
    });



I am not able to upload image with some user data, please let me know what am doing wrong here Thanks

Upvotes: 1

Views: 1586

Answers (1)

Nilesh Solanki
Nilesh Solanki

Reputation: 63

as you are sending form data in body, it will only hold that form data.

if you want to send form data plus some other data, then try to append form data in another object and then append other data in same object with key value pair.

I have created user register form in which I have some input fields and profile upload. For upload I have used "ngx-file-drop".

like:-

const body = {};
body['formData'] = formValues;
body['fileData'] = this.fileDataArray;

In this the ts code is like below.

dropped(files: NgxFileDropEntry[]) {
    this.fileError = false;
    this.files = [];
    this.files = files;
    for (const droppedFile of files) {
      // Is it a file?
      if (droppedFile.fileEntry.isFile && this.isFileAllowed(droppedFile.fileEntry.name)) {
        this.filesArray.push(droppedFile);
        const fileEntry = droppedFile.fileEntry as FileSystemFileEntry;
         const formData: FormData = new FormData();
        fileEntry.file((file: File) => {
          
        });
        fileEntry.file((file: File) => {
          this.dropFilePath.push(droppedFile.relativePath);
          // append form data
          formData.append('upload', file, droppedFile.relativePath);
          this.dropFile.push(file);
          this.dropFileFlag = true;
        });
      } else {
        // It was a directory (empty directories are added, otherwise only files)
        const fileEntry = droppedFile.fileEntry as FileSystemDirectoryEntry;
        this.dropFilePath = [];
        this.dropFile = [];
        this.files = [];

        this.toaster.error('only this file are allowed : [".jpg", ".jpeg",".gif",".png"]', 'Error', {
          positionClass: 'toast-top-full-width',
        });
        break;
      }
    }
  }

and html code is.

<ngx-file-drop [disabled]="isPreview ? true : null" dropZoneLabel="Drop files here" (onFileDrop)="dropped($event)" (onFileOver)="fileOver($event)"(onFileLeave)="fileLeave($event)">
<ng-template ngx-file-drop-content-tmp let-openFileSelector="openFileSelector">
    <span [attr.disabled]="isPreview ? true : null" class="btn">Drop files here or</span>
       <span [attr.disabled]="isPreview ? true : null" (click)="openFileSelector()" class="btn btn-link">click to upload</span>
</ng-template>
</ngx-file-drop>

and on form submit you can do like this.

onSubmit() {
    this.submitted = true;

    if (this.form.invalid || (this.submitted && this.fileError)) {
      this.toaster.error('Invalid form data..!!', 'ERROR');
      return;
    }
    const formData = this.form.value;
    this.fileDataArray.push(formData.getAll('upload'));
    console.log('this.fileDataArray-------->', this.fileDataArray);
    const body = {};
    body['formData'] = formData;
    body['fileData'] = this.fileDataArray;
    console.log('body------>', body);
    // call below your api function
   }

Upvotes: 0

Related Questions