0

I have this vue formulate component

<FormulateInput
          type="image"
          name="property_files"
          v-model="property_images"
          label="Select an images to upload"
          help="Select a png, jpg,webp or gif to upload."
          validation="mime:image/jpeg,image/png,image/gif,image/webp"
          :uploader="uploadFile"
          multiple
/>

i am using to upload multiple images to an express js backend.

This is the express js method

var express = require('express');
var router = express.Router();
var multer = require('multer');

const DIR = './public/';

const MongoClient = require('mongodb').MongoClient;

const url = 'mongodb://localhost:27017';
const dbName = 'dev';


const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, DIR);
  },
  filename: (req, file, cb) => {
    const fileName = file.originalname.toLowerCase().split(' ').join('-');
    cb(null, fileName)
  }
});

var upload = multer({
  storage: storage,
  fileFilter: (req, file, cb) => {
    if (file.mimetype == "image/png" || file.mimetype == "image/jpg" || file.mimetype == "image/jpeg") {
      cb(null, true);
    } else {
      cb(null, false);
      return cb(new Error('Only .png, .jpg and .jpeg format allowed!'));
    }
  }
});

router.get('/', function(req, res, next) {
  res.send('respond with a resource');
});

router.post('/read', upload.array('property_files', 10), (req, res, next) => {
  const reqFiles = []
  const url = req.protocol + '://' + req.get('host')
  for (var i = 0; i < req.property_files.length; i++) {
    reqFiles.push(url + '/public/' + req.property_files[i].filename)
  }
  res.send('happy insert'); 
});

module.exports = router;

This is my vue formulate uploadfile function

    uploadFile: async function (file, progress, error, options) {
    try {
        console.log(file, options);
        const formData = new FormData()
        formData.append('property_files', file)
        const result = await fetch('http://localhost:3000/ca/read', {
            method: 'POST',
            body: formData
        })
        progress(100) // (native fetch doesn’t support progress updates)
        return await result.json()
    } catch (err) {
        error('Unable to upload file')
    }
},

The multiple images are uploaded but soon after, i get this error

TypeError: Cannot read property 'length' of undefined

on this line

for (var i = 0; i < req.property_files.length; i++) {

I would like to rename the uploaded image and remove any special characters on the image names and return the needed format as dictated by vue formulate.

Why is my code throwing the error?

Update

I am able to successfully upload with php

<?php
header('Access-Control-Allow-Origin: *');

header('Access-Control-Allow-Methods: GET, POST');

header("Access-Control-Allow-Headers: X-Requested-With");


$image = '';

if(isset($_FILES['property_files']['name']))
{
 $image_name = $_FILES['property_files']['name'];
 $valid_extensions = array("jpg","jpeg","png");
 $extension = pathinfo($image_name, PATHINFO_EXTENSION);
 if(in_array($extension, $valid_extensions))
 {
  $upload_path = 'uploads/' . uniqid() . '.' . $extension;
  if(move_uploaded_file($_FILES['property_files']['tmp_name'], $upload_path))
  {
   $message = 'Image Uploaded';
   $image = $upload_path;
  }
  else
  {
   $message = 'There is an error while uploading image';
  }
 }
 else
 {
  $message = 'Only .jpg, .jpeg and .png Image allowed to upload';
 }
}
else
{
 $message = 'Select Image';
}
/**
$output = array(
 'message'  => $message,
 'image'   => $image
);
*/
 $output = array(
 'image'   => $image
);
echo json_encode($output);

but i am still interested in handling the uploads in express js.

1 Answer 1

1

TypeError: Cannot read property 'length' of undefined

This means that object property_files is not defined, and you are trying to access property of something that does not exist. Correct object name is files.

From multer API:

.array(fieldname[, maxCount])

Accept an array of files, all with the name fieldname. Optionally error out if more > than maxCount files are uploaded. The array of files will be stored in req.files.

Sign up to request clarification or add additional context in comments.

3 Comments

How then do you access the posted variable in my case, property_files and the images got uploaded btw
You don't. Multer parses the form and creates a object in req.files. By passing property_files to array() you are telling multer where to look for the files in the request body. Then multer does the parsing, saves the files to where you told it to, and puts the file information about the upload in req.files.
If you need to rename the files, read the multer API and create a function for naming files, look for DiskStorage, storage object is responsible for naming files.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.