cloudinary multiple file upload error nodejs - node.js

I am trying to do a multiple file upload using Cloudinary, but for some reason, it only picks the last file I upload and not all 4 of the files, it returns only one file in the array.
Here are the files
Multer.js
const path = require("path");
//setting the storage engine
const storage = multer.diskStorage({
filename: function (req, file, cb) {
cb(
null,
file.fieldname + "-" + Date.now() + path.extname(file.originalname)
);
},
});
// Check File Type
function checkFileType(file, cb) {
// Allowed extension format
const filetypes = /jpeg|jpg|png|pdf/;
// Check the extension format
const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
// Check mime
const mimetype = filetypes.test(file.mimetype);
if (mimetype && extname) {
return cb(null, true);
} else {
req.flash("error", "Invalid File");
cb("ERROR: Please upload a valid filetype");
return res.redirect("back");
}
}
//initialize the file uplaod
const upload = multer({
storage: storage,
//limits file size
fileFilter: function (req, file, cb) {
checkFileType(file, cb);
},
});
module.exports = { upload };
cloudinary.js
const { CLOUDINARY_CLOUD_NAME, CLOUDINARY_API_KEY, CLOUDINARY_API_SECRET } =
process.env;
const cloudinarySetup = async () => {
cloudinary.config({
cloud_name: CLOUDINARY_CLOUD_NAME,
api_key: CLOUDINARY_API_KEY,
api_secret: CLOUDINARY_API_SECRET,
});
};
// cloudinary upload method
const cloudinaryMediaUpload = async (file, folder) => {
await cloudinarySetup();
return new Promise((resolve) => {
cloudinary.uploader.upload(
file,
{
resource_type: "auto",
folder: folder,
},
(err, result) => {
if (err) throw err;
resolve({
url: result.secure_url,
id: result.public_id,
});
}
);
});
};
module.exports = { cloudinaryMediaUpload };
defaultController.js
const { Business } = require("../models/business");
const { cloudinaryMediaUpload } = require(".././config/cloudinary");
module.exports = {
indexGet: (req, res) => {
let pageTitle = "Home";
res.render("default/index", { pageTitle });
},
aboutGet: (req, res) => {
let pageTitle = "About";
res.render("default/about", { pageTitle });
},
contactGet: (req, res) => {
let pageTitle = "Contact";
res.render("default/contact", { pageTitle });
},
registerGet: (req, res) => {
let pageTitle = "Register";
const { businessName, businessAddress, businessPhone } = req.body;
res.render("default/register", {
pageTitle,
businessName,
businessAddress,
businessPhone,
});
},
registerPost: async (req, res) => {
const { businessName, businessAddress, businessPhone, businessCategory } =
req.body;
// console.log(req.body);
console.log(req.files);
let errors = [];
// Checking Required Field
if (
!businessName ||
!businessAddress ||
!businessPhone ||
!businessCategory
) {
errors.push({ msg: "All fields are required" });
}
let validatePhone = validatePhoneNumberSync(businessPhone);
if (!validatePhone.isValid === true) {
errors.push({ msg: "Invalid phone number" });
}
if (errors.length > 0) {
let pageTitle = "Register";
res.render("default/register", {
pageTitle,
businessName,
businessAddress,
businessPhone,
errors,
});
} else {
Business.findOne({ businessName }).then(async (buss) => {
if (buss) {
errors.push({
msg: "A business with this name is already registered",
});
let pageTitle = "Register";
res.render("default/register", {
pageTitle,
businessName,
businessAddress,
businessPhone,
errors,
});
} else {
// uploading files to cloud
const uploader = async (path) => {
const folderName = businessName
.trim()
.toLowerCase()
.replace(/^[^A-Z0-9]+/gi, function (match) {
return arguments[2].toUpperCase();
});
console.log(folderName);
await cloudinaryMediaUpload(path, "folderName");
};
const urls = [];
const files = req.files;
for (const file of files) {
const { path } = file;
const cloudPath = await uploader(path);
urls.push(cloudPath);
}
const newBusiness = new Business({
businessName,
businessAddress,
businessPhone,
businessCategory,
});
newBusiness.save();
req.flash("success_msg", "Business successfully registered");
res.redirect("/");
}
});
}
},
};
register.ejs
<%- include("../partials/default/header") %>
<div class="form_wrapper">
<div class="form_container">
<div class="title_container">
<h2 style="color: #65b54a;">Business Registration</h2>
</div>
<div class="row clearfix">
<div class="">
<%- include ("../partials/messages"); %>
<form action="/register" enctype="multipart/form-data" method="POST">
<div class="row clearfix">
<div class="col_half">
<div class="input_field"> <span><i aria-hidden="true" class="fa fa-user"></i></span>
<input type="text" name="businessName" placeholder="Business Name" required
value="<%= businessName || '' %>" />
</div>
</div>
<div class="col_half">
<div class="input_field"> <span><i aria-hidden="true" class="fa fa-map-marker"></i></span>
<input type="text" name="businessAddress" placeholder="Business Address" required
value="<%= businessAddress || '' %>" />
</div>
</div>
</div>
<div class="row clearfix">
<div class="col_half">
<div class="input_field"> <span><i aria-hidden="true" class="fa fa-phone"></i></span>
<input type="text" name="businessPhone" placeholder="Business Phone Number" required
value="<%= businessPhone || '' %>" />
</div>
</div>
<div class="col_half">
<div class="input_field select_option">
<select name="businessCategory">
<option selected disabled>Business Category</option>
<option>Technology</option>
<option>Agriculture</option>
<option>Fashion</option>
<option>Entertainment</option>
</select>
<div class="select_arrow"></div>
</div>
</div>
</div>
<!-------------------------Files upload section---------------->
<div class="row clearfix">
<div class="col_half">
<div class="input_field d-flex justify-content-around">
<input type="file" name="bussFile" multiple accept=".pdf, .png, .jpg, .jpeg" id="img"
style="display:none;" />
<label for="img" class="btn btn-success"><span class="d-none d-md-inline mr-2"><i aria-hidden="true"
class="fas fa-upload"></i></span>Upload Incorporation Document</label>
</div>
</div>
<div class="col_half">
<div class="input_field d-flex justify-content-around">
<input type="file" name="bussFile" multiple accept=".pdf, .png, .jpg, .jpeg" id="img"
style="display:none;" />
<label for="img" class="btn btn-success"><span class="d-none d-md-inline mr-2"><i aria-hidden="true"
class="fas fa-upload"></i></span>Upload Company's Profile</label>
</div>
</div>
</div>
<div class="row clearfix">
<div class="col_half">
<div class="input_field d-flex justify-content-around">
<input type="file" name="bussFile" multiple accept=".pdf, .png, .jpg, .jpeg" id="img"
style="display:none;" />
<label for="img" class="btn btn-success"><span class="d-none d-md-inline mr-2"><i aria-hidden="true"
class="fas fa-upload"></i></span>Upload Financial Statements</label>
</div>
</div>
<div class="col_half">
<div class="input_field d-flex justify-content-around">
<input type="file" name="bussFile" multiple accept=".pdf, .png, .jpg, .jpeg" id="img"
style="display:none;" />
<label for="img" class="btn btn-success"><span class="d-none d-md-inline mr-2"><i aria-hidden="true"
class="fas fa-upload"></i></span>Upload Investment Pitch Deck</label>
</div>
</div>
</div>
<input class="button" type="submit" value="Register" />
<!-- <button type="submit" class="btn btn-info">
Register
</button> -->
</form>
</div>
</div>
</div>
</div>
<%- include("../partials/default/footer") %>
And this happens to be the array I get back when I submit. Only the last file upload was picked and not all 4 of the uploads
[
{
fieldname: 'bussFile',
originalname: 'tab.png',
encoding: '7bit',
mimetype: 'image/png',
destination: 'C:\\Users\\HP\\AppData\\Local\\Temp',
filename: 'bussFile-1664784129792.png',
path: 'C:\\Users\\HP\\AppData\\Local\\Temp\\bussFile-1664784129792.png',
size: 68329
}
]

When I check out the documentation here -
It looks like only a single "file" is supported at one time.
https://cloudinary.com/documentation/image_upload_api_reference#upload_required_parameters
Details about how to upload more in parallel here:
https://support.cloudinary.com/hc/en-us/articles/202520662-How-can-I-bulk-upload-my-images-#:~:text=Cloudinary's%20upload%20API%20supports%20a,files%20in%20a%20short%20term.

Related

My contact form isn't working with Nodemailer. How do I fix it?

I'm trying to implement email functionality with Node.js, React.js, Nodemailer, and OAuth2 on a contact form
I have two files:
contactForm.js
import React, { useState } from "react";
const App = () => {
const [mailerState, setMailerState] = useState({
name: "",
email: "",
subject:"",
message: "",
});
function handleStateChange(e) {
setMailerState((prevState) => ({
...prevState,
[e.target.name]: e.target.value,
}));
}
const submitEmail = async (e) => {
e.preventDefault();
console.log({ mailerState });
const response = await fetch("/api/server", {
method: "POST",
headers: {
"Content-type": "application/json",
},
body: JSON.stringify({ mailerState }),
})
.then((res) => res.json())
.then(async (res) => {
const resData = await res;
console.log(resData);
if (resData.status === "success") {
alert("Message Sent");
} else if (resData.status === "fail") {
alert("Message failed to send");
}
})
.then(() => {
setMailerState({
name: "",
email: "",
subject:"",
message: "",
});
});
};
return (
<div className="flex justify-center mb-14">
<form className="w-full max-w-lg" onSubmit={submitEmail} >
<div className="flex flex-wrap -mx-3 mb-6">
<div className="w-full md:w-1/2 px-3 mb-6 md:mb-0">
<label
htmlFor="name"
className="block uppercase tracking-wide text-gray-400 text-xs font-bold mb-2"
>
First Name
</label>
<input
className="appearance-none block w-full bg-gray-200 text-gray-700 border border-gray-200 rounded py-3 px-4 mb-3 leading-tight focus:outline-none focus:bg-white"
name="name"
type="text"
placeholder="Ade"
required value={mailerState.name}
onChange={handleStateChange}
/>
</div>
<div className="w-full md:w-1/2 px-3">
<label
htmlFor="name"
className="block uppercase tracking-wide text-gray-400 text-xs font-bold mb-2"
>
Last Name
</label>
<input
className="appearance-none block w-full bg-gray-200 text-gray-700 border border-gray-200 rounded py-3 px-4 leading-tight focus:outline-none focus:bg-white focus:border-gray-500"
name="lastname"
type="text"
placeholder="Banjo"
required value={mailerState.name}
onChange={handleStateChange}
/>
</div>
</div>
<div className="flex flex-wrap -mx-3 mb-6">
<div className="w-full px-3">
<label
htmlFor="email"
className="block uppercase tracking-wide text-gray-400 text-xs font-bold mb-2"
>
E-mail
</label>
<input
className="appearance-none block w-full bg-gray-200 text-gray-700 border border-gray-200 rounded py-3 px-4 mb-3 leading-tight focus:outline-none focus:bg-white focus:border-gray-500"
name="email"
type="email"
aria-describedby="emailHelp"
required value={mailerState.email}
onChange={handleStateChange}
/>
<p className="text-gray-600 text-xs italic">
e.g. example#yahoo.com
</p>
</div>
</div>
<div className="flex flex-wrap -mx-3 mb-6">
<div className="w-full px-3">
<label
htmlFor="message"
className="block uppercase tracking-wide text-gray-400 text-xs font-bold mb-2"
>
Message
</label>
<textarea
className=" no-resize appearance-none block w-full bg-gray-200 text-gray-700 border border-gray-200 rounded py-3 px-4 mb-3 leading-tight focus:outline-none focus:bg-white focus:border-gray-500 h-48 resize-none"
name="message"
required value={mailerState.message}
onChange={handleStateChange}
></textarea>
<p className="text-gray-600 text-xs italic">
</p>
</div>
</div>
<div className="md:flex md:items-center">
<div className="md:w-1/3">
<button
className="shadow bg-indigo-600 hover:bg-indigo-700 focus:ring-indigo-500 focus:ring-offset-indigo-200 text-white w-full transition ease-in duration-200 text-center font-bold py-2 px-1 rounded"
type="button"
>
Send
</button>
</div>
<div className="md:w-2/3"></div>
</div>
</form>
</div>
);
}
export default App;
and
server.js:
const express = require("express");
const app = express();
const nodemailer = require("nodemailer");
const cors = require("cors");
require("dotenv").config();
// middleware
app.use(express.json());
app.use(cors());
// Setting up SMTP for Nodemailer to send mail
const transporter = nodemailer.createTransport({
service: "gmail",
auth: {
type: "OAuth2",
user: process.env.EMAIL,
pass: process.env.WORD,
clientId: process.env.OAUTH_CLIENTID,
clientSecret: process.env.OAUTH_CLIENT_SECRET,
refreshToken: process.env.OAUTH_REFRESH_TOKEN,
},
});
// verify connection configuration
transporter.verify(function (error, success) {
if (error) {
console.log(error);
} else {
console.log(`=== Server is ready to take our messages: ${success} ===`);
}
});
app.post("/api/server", function (req, res) {
let mailOptions = {
from: `${req.body.mailerState.email}`,
to: process.env.EMAIL,
subject: `Message from: ${req.body.mailerState.email}`,
text: `${req.body.mailerState.message}`,
};
transporter.sendMail(mailOptions, function (err, data) {
if (err) {
res.json({
status: "fail",
});
} else {
console.log("== Message Sent ==");
res.json({
status: "success",
});
}
});
});
const port = 5000;
app.listen(port, () => {
console.log(`Server is running on port: ${port}`);
});
They are both in two different folders: contactForm.js is in Components folder and server.js is in pages/api folder.
The Contact form renders perfectly but the email functionality does not. How do I resolve this?
Thanks in advance

Node.js, Multer. video file is saved/uploaded but validator gives an error that video field can not remain empty

I'm trying to upload a video using multer, I have a form and everything but when I click create, validator gives an error however, the file is saved in my directory as if validation was successful.
I'm using mongoDB for database.
here's the validator
const { check } = require('express-validator/check');
const Video = require('app/models/VideoModel');
const path = require('path');
class videoValidator extends validator {
handle() {
return [
check('title')
.isLength({ min : 5 })
.withMessage('title should be at least 5 characters'),
check('artist')
.not().isEmpty()
.withMessage('artist field can not be empty'),
check('videos')
.custom(async (value , { req }) => {
if(req.query._method === 'put' && value === undefined) return;
if(! value)
throw new Error('the video field can not remain empty');
let fileExt = ['.webm' , '.ogg' , '.mp4' , '.avi'];
if(! fileExt.includes(path.extname(value)))
throw new Error('file extention is not supported')
}),
}
slug(title) {
return title.replace(/([^۰-۹آ-یa-z0-9]|-)+/g , "-")
}
}
module.exports = new videoValidator();
video Controller
async create(req , res) {
let artists = await Artist.find({});
res.render('admin/videos/create' , { artists });
}
async store(req , res , next) {
try {
let status = await this.validationData(req);
if(! status) return this.back(req,res);
let videos = req.file;
let { title , artist } = req.body;
let newVideo = new Video({
artist,
title,
slug : this.slug(title),
videos,
});
await newVideo.save();
return res.redirect('/admin/videos');
} catch(err) {
next(err);
}
}
Routes and upload helper
const videoUpload = require('app/helpers/uploadVideo');
// video Routes
router.get('/videos' , videoController.index);
router.get('/videos/create' , videoController.create);
router.post('/videos/create' ,
videoUpload.single('videos'),
videoValidator.handle(),
videoController.store
);
const multer = require('multer');
const path = require('path');
const mkdirp = require('mkdirp');
const fs = require('fs');
const getDirVideo = () => {
let year = new Date().getFullYear();
let month = new Date().getMonth() + 1;
let day = new Date().getDay();
return `./public/uploads/videos/${year}/${month}/${day}`;
}
const videoStorage = multer.diskStorage({
destination : (req , file , cb) => {
let dir = getDirVideo();
mkdirp(dir , (err) => cb(null , dir))
},
filename : (req , file , cb) => {
let filePath = getDirVideo() + '/' + file.originalname;
if(!fs.existsSync(filePath))
cb(null , file.originalname);
else
cb(null , Date.now() + '-' + file.originalname);
}
})
const uploadVideo = multer({
storage : videoStorage,
limits : {
fileSize : 1024 * 1024 * 40
}
});
module.exports = uploadVideo;
Model and ejs
const videoSchema = Schema({
artist: {
type : Schema.Types.ObjectId,
ref : 'Artist'
},
title: {
type : String,
required : true
},
videos: {
type : Object,
required : true
},
time: {
type: String,
default : '00:00:00'
},
videoUrl: {
type : String,
required : true
},
} , { timestamps : true });
module.exports = mongoose.model('Video' , videoSchema);
<div class="d-flex justify-content-between align-items-center mb-3 pb-2 border-bottom">
<h2>add Video</h2>
</div>
<form class="form-horizontal" action="/admin/videos/create" method="post" enctype="multipart/form-data">
<%- include(viewPath('layouts/error-messages')) -%>
<div class="form-group row">
<div class="col">
<label for="title" class="control-label font-weight-bold">Video Title </label>
<input type="text" class="form-control" name="title" id="title" placeholder="video title" value="<%= old('title') %>">
</div>
</div>
<div class="form-group row">
<div class="col">
<label for="artist" class="control-label font-weight-bold font-weight-bold">linked Artist</label>
<select name="artist" id="artist" class="form-control">
<% artists.forEach(artist => { %>
<option value="<%= artist._id %>" <%= String(old('artist')) == String(artist._id) ? 'selected' : '' %> ><%= artist.name %></option>
<% }) %>
</select>
</div>
<div class="col">
<label for="time" class="control-label font-weight-bold">Video Length</label>
<input type="text" class="form-control" name="time" id="time" placeholder="enter video length" value="<%= old('time') %>">
</div>
</div>
<div class="form-group row">
<div class="col">
<label for="videos" class="control-label font-weight-bold">Video File</label>
<input type="file" class="form-control" name="videos" id="videos" placeholder="Enter video file" >
</div>
</div>
<div class="form-group row">
<div class="col">
<button type="submit" class="btn btn-danger">Create</button>
</div>
</div>
</form>
and here's a screen shot of my upload folder that has the video correctly saved in it and it's playable
enter image description here
I just realized I've forgotten to add convertFileToField middleware.
it's working fine now
handle(req , res , next) {
if(! req.file)
req.body.videos = undefined;
else
req.body.videos = req.file.filename;
next();
}

ExpressJs File upload Issue

Even on uploading a file with .jpg or .png format it shows
format not allowed, please upload file with '.png','.gif','.jpg'.
I don't know why it is happening. How to solve or fix this issue? I tried to use ways suggested on some other websites to solve this issue but I wasn't able to fix this issue.
routes.js:
const {
con,
sessionStore
} = require('./config/db');
exports.new = function(req, res){
message = '';
if(req.method == "POST"){
const post = req.body;
const username= post.username;
const title= post.title;
const state= post.state;
const category= post.category;
const description= post.description;
if (!req.files)
return res.status(400).send('No files were uploaded.');
const file = req.files.uploaded_image;
var img_name=file.name;
if(file.mimetype == "image/jpeg" ||file.mimetype == "image/png"||file.mimetype == "image/gif" ){
file.mv('public/imgs/uploads/'+file.name, function(err) {
var sql = "INSERT INTO `nt_data`(`username`,`title`,`state`,`category`, `images` ,`description`) VALUES ?";
var query = con.query(sql, [username, title, state, category, img_name, description], function(err) {
if (!err) {
res.redirect('show/' + username);
}
else {
message = "This format is not allowed , please upload file with '.png','.gif','.jpg'";
res.render('new.ejs',{message: message});
}
});
});
}
}
else {
res.render('new');
}
};
exports.show = function(req, res){
let message = '';
var username = req.params.username;
const sql="SELECT * FROM `nt_data` WHERE `username`='"+username+"'";
con.query(sql, function(err, result){
if(result.length <= 0)
message = "show not found!";
res.render('show.ejs',{data:result, message: message});
});
};
part of my new.ejs file
<form action="/" method="POST" role="form" enctype="multipart/form-data" class="was-validated">
<% if (message.length > 0) { %>
<div class="alert alert-success col-sm-12"><%= message %></div>
<% } %>
<div class="input-group mb-3 input-group-lg">
<div class="input-group-prepend">
<span class="input-group-text">Username</span>
</div>
<input type="text" class="form-control" required placeholder="Enter Username" name="username">
<div class="valid-feedback">Valid.</div>
<div class="invalid-feedback">Please fill out this field.</div>
</div>
<div class="input-group mb-3 input-group-lg">
<div class="input-group-prepend">
<span class="input-group-text">Title</span>
</div>
<input type="text" class="form-control" required placeholder="Enter Title" name="title">
<div class="valid-feedback">Valid.</div>
<div class="invalid-feedback">Please fill out this field.</div>
</div>
<div class="custom-file mb-3">
<input type="file" class="custom-file-input" id="customFile" name="uploaded_image">
<label class="custom-file-label" for="uploaded_image">Choose file</label>
</div>
You should use multer for image or file uploading to server. Because you must use buffer to transfer data from user to local or public server and must create session. You can do these using multer easily.
You can check
https://www.npmjs.com/package/multer

Express.js application bug: Cannot read property 'transfer-encoding' of undefined

I am working on a blogging application (click the link to see the GitHub repo) with Express, EJS and MongoDB.
I am trying to introduce an add post image feature. Being quite new to Express, I am puzzled about the problem I have ran into.
The add post form:
<form action="/dashboard/post/add" method="POST" enctype="multipart/form-data" class="mb-0">
<div class="form-group">
<input type="text" class="form-control" name="title" value="<%= typeof form!='undefined' ? form.titleholder : '' %>" placeholder="Title" />
</div>
<div class="form-group">
<input type="text" class="form-control" name="excerpt" value="<%= typeof form!='undefined' ? form.excerptholder : '' %>" placeholder="Excerpt" />
</div>
<div class="form-group">
<textarea rows="5" class="form-control" name="body" placeholder="Full text"><%= typeof form!='undefined' ? form.bodyholder : '' %></textarea>
</div>
<label for="postimage">Upload an image</label>
<div class="form-group">
<input type="file" name="postimage" id="postimage" size="20">
</div>
<div class="form-group d-flex mb-0">
<div class="w-50 pr-1">
<input type="submit" value="Add Post" class="btn btn-block btn-md btn-success">
</div>
<div class="w-50 pl-1">
Cancel
</div>
</div>
</form>
In the controller my addPost() methos looks like this:
const Post = require('../../models/post');
const { validationResult } = require('express-validator');
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './uploads/images')
},
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now() + '.png')
}
});
const upload = multer({ storage: storage }).single('postimage');
exports.addPost = (req, res, next) => {
upload(function(err) {
if (err) {
console.log("There was an error uploading the image.");
}
res.json({
success: true,
message: 'Image uploaded!'
});
})
var form = {
titleholder: req.body.title,
excerptholder: req.body.excerpt,
bodyholder: req.body.body
};
const errors = validationResult(req);
const post = new Post();
post.title = req.body.title;
post.short_description = req.body.excerpt;
post.full_text = req.body.body;
if (!errors.isEmpty()) {
req.flash('danger', errors.array())
res.render('admin/addpost', {
layout: 'admin/layout',
website_name: 'MEAN Blog',
page_heading: 'Dashboard',
page_subheading: 'Add New Post',
form: form
});
} else {
post.save(function(err) {
if (err) {
console.log(err);
return;
} else {
req.flash('success', "The post was successfully added");
req.session.save(() => res.redirect('/dashboard'));
}
});
}
}
I alse have const multer = require("multer"); at the top (of the controller).
The "Add New Post" form worked fine until I tried to add this upload feature. The code I currently have throws this error:
Cannot read property 'transfer-encoding' of undefined
at hasbody (C:\Path\To\Application\node_modules\type-is\index.js:93:21)
What am I doing wrong?
You are missing req and res inside your upload(), try adding those two like
upload(req, res, function (err) {
if (err) {
console.log("There was an error uploading the image.");
}
res.json({
success: true,
message: 'Image uploaded!'
});
})

Uploading image with vuejs to Nodejs Server not working

Sending form data with text content to Nodejs server from vuejs front end but the file is never uploaded to the server. I had been stack for a while now. Here is my detailed front and backend code:
Front End
//Front end VueJS
Upload form component
<template>
<div class="container">
<form v-on:submit.prevent="addMember" method="post">
<div class="row">
<div class="col-sm-10 col-md-10 col-lg-10">
<div class="form-group">
<label>Title<span class="required-field">*</span>:</label>
<input type="text" class="form-control" v-model="member.title" name="title" v-validate="'required|min:10'">
<div class="help-block alert alert-danger" v-show="errors.has('title')">
{{errors.first('title')}}
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-10 col-md-10 col-lg-10">
<div class="form-group">
<label>Full Name<span class="required-field">*</span>:</label>
<input type="text" class="form-control" v-model="member.fullname" name="fullname" v-validate="'required|min:10'">
<div class="help-block alert alert-danger" v-show="errors.has('fullname')">
{{errors.first('fullname')}}
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-10 col-md-10 col-lg-10">
<div class="form-group">
<label>Passport Photo
<input type="file" id="file" ref="photo" v-on:change="handleFileUpload()"/>
</label>
</div>
</div>
</div>
</form>
<div class="row">
<div class="col-sm-10 col-md-10 col-lg-10">
<div class="form-group">
<button class="btn btn-info btn-lg pull-right">Save</button>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name:'CreateMember',
data(){
return{
member:{},
photo:'',
}
},
},
methods: {
handleFileUpload(){
this.coverimage = this.$refs.photo.files[0]
},
addMember(){
this.$validator.validateAll().then(()=>
{
let formData = new FormData();
formData.append('file', this.photo);
let rawData = this.member
rawData = JSON.stringify(rawData)
formData.append('data',rawData)
this.axios.post('/members',this.member,{
'content-type':'multipart/form-data'
}).then((resp)=>{
console.log(resp.data)
//this.$router.push({name: 'members'})
}).catch((error)=>{
console.log(error)
})
});
}
}
}
</script>
Back End (Nodejs and Express)
**routes/members.js**
var express = require('express');
var router = express.Router();
//Require Controller Modules
var controller = require('../controllers/MembersController');
var auth = require('../middleware/auth');
const path = require('path');
const multer = require('multer');
//Define file storage engine
const storage = multer.diskStorage({
destination:'public/uploads/',
filename: (req,file,cb)=>{
cb(null,file.fieldname+'-'+Date.now()+path.extname(file.originalname));
}
});
//Filter uploaded file and only upload file types of enumerated format
const fileTypeFilter = (req, file, cb)=>{
if(file.mimetype==='image/jpeg'||file.mimetype==='image/jpg'|| file.mimetype==='image/png'){
cb(null, true);
}
else{
cb(new error('Invalid Image Format'), false);
}
}
const upload = multer({storage:storage,
limits:
{
fileSize:1024*1024*1000
},
filefilter:fileTypeFilter
});
//Save new member to the database
router.post('/members', upload.single('photo'),auth,controller.createMember);
Controllers/MembersController.js
var express = require('express');
var router = express.Router();
const fs = require('fs');
const Model = require('../models/index');
const Member = Model.sequelize.import('../models/member');
//createMember Controller Method
exports.createMember = function(req, res, next) {
//Check if the cover image is attached
if(!req.file)
{
return res.status(400).json({message:'Attach Photo!'}); //The request is returning this response, meaning the file is never uploaded. And the file actually is not being uploaded
}
Member.create({
title: req.body.title,
fullname : req.body.fullname,
photo : req.body.req.file.path
}).then(member=>{
res.json(member);
}).catch((error)=>{
return res.json({status:500,error:error});
});
};
Removing file from request the rest of the data is saved into the database as expected
Model
//Models/member.js
'use strict';
module.exports = (sequelize, DataTypes) => {
var Member = sequelize.define('Member', {
fullname: DataTypes.STRING,
photo: DataTypes.STRING
}, {});
Member.associate = function(models) {
// associations can be defined here
};
return Member;
};
What may be doing wrong. The upload directory is empty. please help me out.

Resources