Есть ли способ вызвать функцию, чтобы ослабить все файлы перед загрузкой новых с помощью multer? - PullRequest
0 голосов
/ 03 апреля 2019

Я пытаюсь передать функцию ereaseFiles() до вызова метода upload.array(), но я не могу понять, как это сделать.

Основная цель - запрос на удаление всех файлов на диске, связанных с этим объектом, перед загрузкой новых.

Я пытался установить функцию в разделе diskStorage, а также в обратном вызове пут пут. Я даже пытался обработать его в самой функции до вызова метода upload.array(). Я пытался работать с обещаниями, но это слишком сложно для меня.

//function to be called (this works)
function ereaseFiles(req) {
    glob("uploads/" + req.body.numeroScheda + "*", function (err, files) {
        for (const file of files) {
            fs.unlink(file, err => {
                if (err) throw err;
                console.log('successfully deleted files');
            });
        }
    });
}

//My multer setup:

const storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, './uploads/');

    },
    filename: function (req, file, cb) {
        cb(null, req.body.numeroScheda + "-" + file.originalname);
    }
});

const upload = multer({
    storage: storage, limits: {
        fileSize: 1024 * 1024 * 2,
    },
});

//MY EDIT PUT ROUTE
app.put("/immobili/:_id", upload.array('immaginePrincipale', 30), function (req, res) {

    const requestedId = req.params._id;
    const proprietaImmagini = req.files;
    const immagini = proprietaImmagini.map(function (immagine) {
        //console.log(immagine.path);
        return immagine.path;
    });

    Immobile.findOneAndUpdate(requestedId, {
        numeroScheda: req.body.numeroScheda,
        categoria: req.body.categoria,
        titolo: req.body.titolo,
        sottotitolo: req.body.sottotitolo,
        descrizione: req.body.descrizione,
        localita: req.body.localita,
        locali: req.body.locali,
        superficie: req.body.superficie,
        camere: req.body.camere,
        bagni: req.body.bagni,
        immagini: immagini,
    }, function (err, updatedImmobile) {
        if (err) return console.error(err);

        res.redirect("/immobili/" + requestedId);
    });
});

Что должно произойти, это то, что все файлы на диске, связанные с объектом (numeroScheda), удаляются до загрузки новых, чтобы автоматизировать и очистить хранилище файлов.

РЕДАКТИРОВАТЬ 1:

Я создал маршрут удаления, который работает:

app.delete("/immobili/:_id", (req, res) => {

    const requestedId = req.params._id;

    Immobile.findOne({ _id: requestedId }, function (err, immobile) {
        if (err) return console.error(err);
        ereaseFiles(immobile);
    });

    Immobile.findOneAndRemove(requestedId, err => {
        if (err) console.error(err);
        else res.redirect('/immobili');
    });
});

функция ereaseFiles теперь выглядит так:

ereaseFiles = immobile => {
    glob("uploads/" + immobile.numeroScheda + "*", function (err, files) {
        for (const file of files) {
            fs.unlink(file, err => {
                if (err) throw err;
            });
        }
    });
cancellato = true;
}

Я попытался реализовать это в маршруте редактирования с помощью промежуточного программного обеспечения, как любезно предложено с этим:

app.use("/immobili/:_id", function (req, res, next) {
    const requestedId = req.params._id;

    let timer = setInterval(() => {
        Immobile.findOne({ _id: requestedId }, (err, immobile) => {
            if (err) return console.error(err);
            ereaseFiles(immobile);
            console.log(this.cancellato);
            if (this.cancellato) {
                clearInterval(timer);
                next();
            }
        });
    }, 1000);
});

Это работает, если загруженные изображения больше или одинаковы, чем раньше, но если меньше, они выводятся со странным поведением (иногда загружаются некоторые изображения, иногда нет).

Ответы [ 2 ]

0 голосов
/ 04 апреля 2019

Я выиграл!Решением было поставить небольшой таймер на функцию next(), так как она запускалась слишком рано, и загрузки и смешивание двух.Спасибо всем за помощь!

Я также добавил переменную ereased, которая выключалась и включалась по завершении функции.Спасибо мистеру Вебу за это.

Вот ответ, если кто-то сталкивается с этим, в коде есть какой-то итальянский язык, надеюсь, в любом случае достаточно читаемый!

cancellaFoto = immobile => {
    cancellato = false;
    glob("uploads/" + immobile.numeroScheda + "*", function (err, files) {
        for (const file of files) {
            fs.unlink(file, err => {
                if (err) throw err;
            });
        }
    });
    cancellato = true;
}

app.use("/immobili/:_id", function (req, res, next) {

    const requestedId = req.params._id;

    Immobile.findOne({ _id: requestedId }, (err, immobile) => {
        if (err) return console.error(err);
        immobile.immagini = [];
        cancellaFoto(immobile);
        console.log(immobile.immagini);
        if (this.cancellato) {
            console.log(this.cancellato);
            return setTimeout(next, 500);
        } else {
            return console.log("Aborted");
        }
    });
});

//EDIT PUT ROUTE
app.put("/immobili/:_id", upload.array('immaginePrincipale', 30), function (req, res) {

    const requestedId = req.params._id;

    const proprietaImmagini = req.files;
    const immagini = proprietaImmagini.map(function (immagine) {
        //console.log(immagine.path);
        return immagine.path;
    });
    console.log(immagini);
    Immobile.findOneAndUpdate(requestedId, {
        numeroScheda: req.body.numeroScheda,
        categoria: req.body.categoria,
        titolo: req.body.titolo,
        sottotitolo: req.body.sottotitolo,
        descrizione: req.body.descrizione,
        localita: req.body.localita,
        locali: req.body.locali,
        superficie: req.body.superficie,
        camere: req.body.camere,
        bagni: req.body.bagni,
        immagini: immagini,
    }, function (err, updatedImmobile) {
        if (err) return console.error(err);

        res.redirect("/immobili/" + requestedId);
    });
});
0 голосов
/ 03 апреля 2019

Вы можете использовать промежуточное программное обеспечение для этого. Просто убедитесь, что промежуточное ПО расположено перед вашим обработчиком запросов put.

app.use("/immobili/:_id", function(req,res,next){
eraseFiles(req);
let timer = setInterval(() => {
if(erased){
clearInterval(timer);
next();    
}
},100);

})

app.put("/immobili/:_id", upload.array('immaginePrincipale', 30), function (req, res) { ...

РЕДАКТИРОВАТЬ 1:

Пожалуйста, измените вашу функцию eraseFiles на:

function ereaseFiles(req) {
glob("uploads/" + req.body.numeroScheda + "*", function (err, files) {
    for (let i=0;i<files.length-1;i++) {
        fs.unlink(files[i], err => {
            if (err) throw err;
            console.log('successfully deleted files');
            if(i===files.length-1)
             erased = true;
        });
    }
});
}

Редактировать 2: многое изменилось. Теперь подход заключается в том, что ваш маршрут сначала пойдет в промежуточное ПО. Ваша функция eraseFiles будет вызвана. Хотя стертая переменная не является истинной, ваш маршрут пут не будет достигнут. Когда функция erasedFiles будет завершена, для нее будет установлено значение true. Чтобы это работало, вы должны установить в файле значение erased = false перед этим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...