Home > Blockchain >  multer. How can I skip a file if it is on disk?
multer. How can I skip a file if it is on disk?

Time:11-26

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}`)
})
  • Related