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.
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.