I just can't figured whats wrong why my codes below. I try to upload multiple files.
The problem is that i had an "UNEXPECTED FIELD"
I can make it to upload single file just fine, but I can't make it upload multiple files. So what's wrong here?
html
<input id="file" type="file" class="form-control" placeholder="Imagen" name="image" multiple>
component.js
var payload = new FormData();
var files = $('#file')[0].files
for (key in $scope.producto) {
payload.append(key, $scope.producto[key])
console.log($scope.producto[key])
}
if (files.length > 0) {
for (var i = 0; i < files.length; i++) {
var file = files[i];
console.log(file)
console.log(files.length)
payload.append('image', file);
}
}
$http.post('http://localhost:5001/api/v1/articles', payload, {
transformRequest: angular.identity,
headers: { "Content-Type": undefined },
}).then(function (response) {
$location.path("/")
})
Here's the server part:
const multer = require('multer')
const storage = multer.diskStorage({
destination : function(req, file, cb){
cb(null, './uploads/');
},
filename : function(req, file, cb){
cb(null, new Date().toISOString() + file.originalname)
}
})
const upload = multer({storage : storage, limits: {
fileSize : 1024 * 1024 * 5
}})
.post('/api/v1/articles/', upload.array('image', 2 ), controllerArticle.postArticles)
controllerArticle.js
function postArticles(req, res) {
// console.log(req.file)
if (req.file) {
const nvo = new articulos({
name: req.body.name,
price: req.body.price,
condition: req.body.condition,
brand: req.body.brand,
productImage: req.file.path
})
nvo.save((err, productStored) => {
if (err) res.status(500)
res.status(200).send({ nvo: productStored })
})
}
}
I have tried so far:
Change upload.array() to upload.any(),and doesn't work..
any help? thanks!
Already solved... The problem was in the controller.
Is req.files not req.file (singular).
if I just need to upload one file it's req.file and to multiple files is req.files.
Related
I have array with buffer files. I have been trying upload buffers to express server using multer for whole day.
Problem is my files pass by req.body.image. But multer finds files from req.files. Multer can't found files and alerted error. How fix this problem?
Front End code:
let UserPhoto = ["data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4gIoSUNDX1BST0ZJTEUAAQEAAAIYAAAAAAQwAABtbnRyUkdCIFhZWiAAAAAAAAAAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAA"];
let formData = new FormData();
for (let i = 0; i < userPhoto.length; i++) {
formData.append("files", userPhoto[i]);
}
axios
.post(`v0/photo/${id}/User`, formData, {
headers: { "Content-Type": "multipart/form-data" },
})
.then((result) => {
console.log(result);
})
.catch((error) => {
console.log(error);
}
Back End code:
const fileFilter = (req, file, cb) => {
if (file.mimetype.substr(0, 6) === "image/") {
cb(null, true);
} else cb(new ErrorCatcher("Зөвхөн зураг upload хийнэ үү.", 400), false);
};
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, director);
},
filename: (req, file, cb) => {
cb(null, Date.now() + "." + file.mimetype.split("/")[1]);
},
});
const upload = multer({
storage: storage,
limits: { fileSize: process.env.IMAGE_MAX_SIZE },
fileFilter: fileFilter,
});
//authorize,
// permission("user", "operator", "manager", "admin"),
router
.route("/:objectId/:objectType")
.post(upload.array("files", 8), createImageConnect);
I was using formData. Result was same.
I simply have this on my server
const storage = multer.diskStorage({
destination: "public/something/images",
filename: function (req, file, cb) {
console.log(file, "file?");
cb(
null,
file.fieldname + "-" + Date.now() + path.extname(file.originalname)
);
},
});
var upload = multer({ storage: storage });
app.post("/upload", upload.single("file"), (req, res) => {
console.log(req.file, "req?"); // this is undefined?
console.log(req.files.File, "req?"); // this is the correct file. why does the line above not work?
res.json({ file: req.file });
});
on my frontend I have:
<input type="file" name="file" onChange={changeHandler} />
public/something/images does get created but the image is not inside it, why is this happening?
request:
const endpoint = () => {
const formData = new FormData();
formData.append("File", selectedFile);
fetch("http://localhost:4000/upload", {
method: "POST",
body: formData,
})
.then((r) => r.json())
.then((a) => console.log(a));
};
i use multer package with node and react and i send a file to node js backend, but always its undefined..
This is React
<div className="file-field input-field">
<div className="btn">
<span>File</span>
<input
type="file"
name="image"
id="image"
onChange={changedImageUpload}
/>
</div>
<div className="file-path-wrapper">
<input className="file-path validate" />
</div>
</div>
and that is onChange file handling method in there i just get first console.log but second and third is not printed
const changedImageUpload = (e) => {
const file = e.target.files[0];
const formData = new FormData();
formData.append("image", file);
console.log(formData, file);
try {
const config = {
Headers: {
"Content-Type": "multipart/form-data",
},
};
axios
.post("/uploads", formData, config)
.then((res) => {
console.log(res.data);
})
.catch((err) => {
console.log(err);
});
} catch (err) {
console.log(err);
}
};
and its Node codes and multer configure
import express from "express";
import multer from "multer";
const route = express.Router();
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, "images");
},
filename: (req, file, cb) => {
cb(
null,
new Date().toISOString().replace(/[\/\\:]/g, "_") + file.originalname
);
},
});
const multerFilter = (req, file, cb) => {
if (
file.mimetype === "image/png" ||
file.mimetype === "image/jpg" ||
file.mimetype === "image/jpeg"
) {
cb(null, true);
} else {
cb(null, false);
}
};
const upload = multer({ storage: storage, fileFilter: multerFilter });
route.post("/uploads", upload.single("image"), (req, res) => {
try {
// res.send(`/${req.file.path}`);
console.log(req.file);
} catch (err) {
console.log(err);
}
});
and import in app.js
import uploadRoutes from "./Routes/uploadRoutes.js";
app.use(uploadRoutes);
const __dirname = path.resolve();
app.use("/images", express.static(path.join(__dirname, "/images")));
so at printing formData i always get empty object, and if i print req.file i get an undefined in node js
Your filter function is wrong. You are comparing the mimeType to things like jpg which isn't a real MIME type, so your files are always filtered out.
You need to compare to image/png and image/jpeg instead.
I need to post an array of images and a single image for product preview.
Here my multer settings
const multer = require('multer');
// Multer settings
const storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, './uploads/');
},
filename: function(req, file, cb) {
cb(null, file.originalname);
}
});
const fileFilter = (req, file, cb) => {
// reject a file
if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png') {
cb(null, true);
} else {
cb(null, false);
}
};
const upload = multer({
storage: storage,
fileFilter: fileFilter
});
const multerSettings = upload.fields([{ name: 'thumb', maxCount: 1 }, { name: 'images', maxCount: 8 }]);
module.exports = multerSettings;
My model for posting data. I am using MongoDB
thumb: {
url: String
},
images: [{url: String}]
Client part
const fd = new FormData();
const { images, thumb } = state.details;
fd.append('thumb', thumb);
fd.append('images', images);
await this.$axios.post('/product', fd);
Images are an array of files [File, File, File], and for some reason, req.files['images'] is undefined on the server, but thumb works properly. And when I am sending the same data via postman all works as expected. In the browser in header preview i see the following data
thumb: (binary)
images: [{},{},{}]
Maybe images should be an array of binary data?
And when sending a single file like this
fd.append('images', images[0]);
req.files['images'] its work properly. I need somehow modify my array on the client. By i have no idea what i should do.
I would be grateful for any tips
The solution is pretty simple.
const fd = new FormData();
const { images, thumb } = state.details;
fd.append('thumb', thumb);;
for(let i = 0; i < images.length; i++) {
fd.append('images', images[i]);
}
await this.$axios.post('/product', fd);
const files = new FormData();
files.append('files', data);
const res = await httpApi.post('/user/upload', files, {headers: { 'Content-Type': 'multipart/form-data'}});
This works! :)
I am able to upload a single file using multer. But when it comes to multiple files it won't work anymore and no file is caught by multer.
I send files through formData.append(). But it only uploads single file
Vue component
const formData = new FormData();
formData.append("productImg", this.imgFile);
this.$store.dispatch(POST_PRODUCT_IMAGE, formData)
.then((response) => {
console.log(response.data);
})
.catch(error => {
console.log(error);
})
Server file
const uploadPath = path.join(__dirname, '/../../public/uploads');
var storage = multer.diskStorage({
destination: (req, file, callback) => {
callback(null, uploadPath + "/garbage/productImg");
},
filename: (req, file, callback) => {
var newName = Date.now() + "_" + file.originalname;
callback(null, newName);
}
});
const upload = multer({
storage: storage
});
productRouter.post('/uploadProductImage', upload.any(), async (req, res) => { // Some Code })
I did also
productRouter.post('/uploadProductImage', array('productImg[]', 6), async (req, res) => { // Some Code })
I want to upload multiple files at a time to my specified folder.
Finally i found a solution which is very silly though.
In Vue component file i just use a loop before add in formData. Like this.
Vue Component
const formData = new FormData();
// formData.append("productImg", this.imgFile); // OLD ONE
for (let index = 0; index < this.imgFile.length; index++) { //NEW ONE
let file = this.imgFile[index];
formData.append("productImg["+index+"]", file);
}
this.$store.dispatch(POST_PRODUCT_IMAGE, formData)
.then((response) => {
console.log(response.data);
})
.catch(error => {
console.log(error);
})