How can I skip a file using multer upload if it is already on disk? It re-downloads and updates when I use the following code
attachments.component.js
import React, { Component } from 'react';
import axios from 'axios';
export default class FilesUploadComponent extends Component {
constructor(props) {
super(props);
this.onFileChange = this.onFileChange.bind(this);
this.onSubmit = this.onSubmit.bind(this);
this.state = {
imgCollection: ''
}
}
onFileChange(e) {
this.setState({ imgCollection: e.target.files })
}
onSubmit(e) {
e.preventDefault()
let formData = new FormData();
for (const key of Object.keys(this.state.imgCollection)) {
formData.append('imgCollection', this.state.imgCollection[key])
}
axios.post("/api/attachments/upload", formData, {
}).then(() => {}).catch(() => {})
}
render() {
return (
<div className="container">
<div className="row">
<form onSubmit={this.onSubmit}>
<div className="form-group">
<input type="text" name="FIO" />
</div>
<div className="form-group">
<input type="file" name="imgCollection" onChange={this.onFileChange} multiple />
</div>
<div className="form-group">
<button className="btn btn-primary" type="submit">Upload</button>
</div>
</form>
</div>
</div>
)
}
}
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
attachments.router.js
let express = require('express'),
multer = require('multer'),
router = express.Router(),
Attachment = require('../models/Attachment');
const DIR = './public/';
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, DIR);
},
filename: (req, file, cb) => {
const fileName = file.originalname;
cb(null, fileName)
}
});
const upload = multer({
storage: storage
});
router.post('/upload', upload.array('imgCollection'), async (req, res) => {
try{
const reqFiles = [];
for (let i = 0; i < req.files.length; i ) {
const file_name = 'public/' req.files[i].filename
reqFiles.push(file_name)
const find = await Attachment.findOne({ file_name: file_name })
if(find){
return res.status(400).json( { message: 'File ' file_name ' already save' } )
}
}
console.log(reqFiles)
reqFiles.map(async name => {
const attachment = new Attachment({
file_name: name
})
await attachment.save()
})
res.status(201).json({ message: 'Files saved' })
}catch (e) {
console.log(e.message)
}
})
module.exports = router;
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Attachment.model.js
const {Schema, model} = require('mongoose')
const schema = new Schema({
file_name: {
type: String, required: true, unique: true
}
},
{
timestamps: true
})
module.exports = model('Attachment', schema)
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Ideally, I would like to first perform some operations in mongodb, then give the correct answer to the user, but to get the necessary data, I first save the files using multer. Tell me what I'm doing wrong
CodePudding user response:
Make use of the fileFilter
function. Here's a full example:
const express = require('express')
const multer = require('multer')
const fs = require('fs')
const path = require('path')
const app = express()
const port = 3000
const UPLOAD_DIR = '/tmp/'
const fileFilter = (req, file, cb) => {
if (fs.existsSync(path.join(UPLOAD_DIR, file.originalname))) {
console.log('skipped')
cb(null, false)
return
}
cb(null, true)
}
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, UPLOAD_DIR)
},
filename: function (req, file, cb) {
const fileName = file.originalname;
cb(null, fileName)
}
})
const upload = multer({
fileFilter,
storage,
});
app.post('/', upload.single('avatar'), (req, res) => {
res.send('Uploaded!')
})
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})