Unable to upload image/video files from react-native to nodejs

Viewed 625

I am using expo-image-picker in react-native to pick image/video files and multer in nodejs as middleware to download files in directory /public/upload. When i am uploading file along with other parameters from react-native, multer is unable to detect a file present in req.body and hence not downloading any file.

Here is my react-native code using axios

pickImage = async () => {
    try {
      let options = {
        mediaTypes: ImagePicker.MediaTypeOptions.Images,
        quality: 1,
        // base64:true
      }

      let result = await ImagePicker.launchImageLibraryAsync(options)
      if (!result.cancelled) {
        this.setState({ content: result })
      }
    } catch (E) {
      console.log("error in picking image:", E)
    }
  }

createFormData = (response) => {
    const photo = {
      uri: response.uri,
      type: response.type,
      name: "my-img.jpg",
    };
    const form = new FormData();
    form.append('acivityFile',photo);
    return form;
  };

handleSubmit = async () => {
    if (this.state.content) {
      const formData = this.createFormData(this.state.content)
      console.log("form data:", formData)
      try {
        const res = await axios.post('http://393ad751391b.ngrok.io/activities',
          {
          title: "This is the title",
          description: "This is a description",
          eventType: "LOST & FOUND",
          file: formData
        },
          {
            headers: {
              'Accept': 'application/json',
              'Content-Type': 'multipart/form-data'
            },
          },
        )
        console.log("res:", res.data);
      } catch (err) {
        console.log("err in post axios:",err)
      }
    }
  }

Here is my route file handling http requests in server-side

const express = require('express');
const Upload = require('./../utils/multerSetup');
const activityController = require('../Controllers/activityController');

const router = express.Router();

router
  .route('/')
  .get(activityController.getAllActivities)
  .post(
    Upload.single('activityFile'),
    activityController.addActivity
  );

Here is my multerSetup.js file in server-side

const multer = require('multer');

const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, 'public/uploads/');
  },
  filename: function (req, file, cb) {
    const ext = file.mimetype.split('/')[1];
    cb(null, file.fieldname + '-' + Date.now() + '.' + ext);
  },
});

const upload = multer({ storage });

module.exports = upload;

Here is my activityController.js file in server-side

const Activity = require('./../modals/activityModel');
const User = require('./../modals/user');

exports.getActivity = async (req, res, next) => {
  console.log('here');
  const activity = await Activity.findById(req.params.id);
  res.status(200).json({
    status: 'success',
    data: {
      activity,
    },
  });
};

exports.addActivity = async (req, res, next) => {
  if (req.file) {
    let file = {
      Ftype: req.file.mimetype.split('/')[0],
      name: req.file.filename,
    };
    req.body.file = file;
  }
  if (!req.body.location) {
    req.body.location = {
      coordinates: ['77.206612', '28.524578'],
    };
  }
  if (req.body.votes) {
    req.body.votes.diff = req.body.votes.up - req.body.votes.down;
  }
  req.body.creator = "12345" || "req.userId";
  const activity = await Activity.create(req.body);
  res.status(201).json({
    status: 'success',
    data: {
      activity,
    },
  });
};

Also when Content-type:'multipart/form-data, then server console throws Error: Multipart:Boundary not found. When i use Content-type:'application/json', then multer does not work.

I just want to know what is the correct way of uploading files with additional parameters from react-native to nodejs multer. Any suggestions would be a great help!

0 Answers
Related