Загрузить несколько изображений с помощью узла в проблеме с картой s3 - PullRequest
0 голосов
/ 27 мая 2020

Я изо всех сил пытаюсь найти решение для загрузки двух файлов в s3. Я могу загрузить один файл с помощью multer, и я научился это делать, но когда я пытаюсь сделать карту внутри всех файлов в formdata и загрузить каждый файл, я помещаю sh в массив каждого URL-адреса местоположения, который является единственным Сохраняю в своей базе. Затем я пытаюсь распечатать каждый URL-адрес, но, к моему удивлению, они печатаются внутри оператора if, но не тогда, когда я сохраняю его в базе данных вне if. Может быть, из-за асинхронной проблемы ?. Спасибо.

tournamentsCtrl.createTournament = async (req, res) => {
    var files_upload = []
    if (req.files) {
        aws.config.setPromisesDependency();
        aws.config.update({
            accessKeyId: process.env.AWS_ACCESS_KEY_ID,
            secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
            //region: process.env.REGION
        });
        const s3 = new aws.S3();
        req.files.map((item) => {
            var params = {
                ACL: 'public-read',
                Bucket: process.env.AWS_BUCKET_NAME,
                Body: fs.createReadStream(item.path),
                Key: `tournament_img/${uuidv4()/* +req.file.originalname */}`
            };

            await s3.upload(params, (err, data) => {
                if (err) {
                    console.log('Error occured while trying to upload to S3 bucket', err);
                }
                if (data) {
                    fs.unlinkSync(item.path); // Empty temp folder
                    const locationUrl = data.Location;
                    files_upload.push(locationUrl);
                    console.log(files_upload)
                }
            });
        });
    }
    console.log(files_upload)
    const new_data = { ...JSON.parse(req.body.values), img_source: files_upload[0], info_url: files_upload[1] }
    console.log(new_data)
    const newUser = new Tournaments(new_data);
    newUser
        .save()
        .then(user => {
            res.json({ message: 'User created successfully', user });
        })
        .catch(err => {
            console.log('Error occured while trying to save to DB');
        });
};

Ответы [ 3 ]

1 голос
/ 27 мая 2020

Если вы посмотрите документацию для upload , он не возвращает обещание, поэтому вы не должны вызывать для него await. Метод карты по умолчанию несовместим с кодом asyn c в этой форме. Вам нужно либо использовать asyn c .map , либо обернуть асинхронный c код в обещание, например

return await new Promise((resolve, reject) => {
...
    if (data) {
      fs.unlinkSync(item.path);
      resolve(data.location);
    }

}

Другой ваш код также имеет некоторые проблемы. Функция карты должна возвращать значение. Если вы не хотите ничего возвращать, используйте foreach.

0 голосов
/ 30 мая 2020

Это плохое место, чтобы попросить совета по коду, но что-то вроде следующего

function uploadFile(s3, element) {
    return new Promise((resolve, reject) => {
        let folder;
        if (element.fieldname.includes('img')) {
            folder = 'club_images'
        } else if (element.fieldname.inlcudes('poster')) {
            folder = 'poster_tournament'
        } else {
            folder = 'info_tournament'
        }
        const params = {
            ACL: 'public-read',
            Bucket: process.env.AWS_BUCKET_NAME,
            Body: fs.createReadStream(element.path),
            Key: `${folder + '/' + uuidv4() + element.fieldname}`
        };
        s3.upload(params, (err, data) => {
            if (err) {
                return reject(err);
            }

            if (data) {
                return fs.unlink(element.path, err=> {
                    if(err) {
                        console.error("Failed to unlink file", element.path);
                    }
                    return resolve({[element.fieldname]: data.Location});
                }); // Empty temp folder
            }
            return resolve();

        });
    })
}

tournamentsCtrl.createTournament = async (req, res) => {
    aws.config.setPromisesDependency();
    aws.config.update({
        accessKeyId: process.env.AWS_ACCESS_KEY_ID,
        secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
        //region: process.env.REGION
    });
    const s3 = new aws.S3();

    try {
        const uploadData = await Promise.all(req.files.map(element => uploadFile(s3, element)));
        const returnData = Object.assign({}, ...uploadData);
        console.log(Object.assign(JSON.parse(req.body.values), returnData));
    } catch(e) {
        console.error('Failed to upload file', e);
        return res.sendStatus(500);
    }

    const newUser = new Tournaments(Object.assign(JSON.parse(req.body.values), files_upload));
    console.log(newUser)
    try {
        const user = await newUser.save()
        res.json({message: 'User created successfully', user});
    } catch(e) {
        console.error('Error occured while trying to save to DB');
        return res.sendStatus(500);
    }
};
0 голосов
/ 29 мая 2020

Я пытался исправить проблему, но не могу :( Это мой новый код.

tournamentsCtrl.createTournament = async (req, res) => {
    aws.config.setPromisesDependency();
    aws.config.update({
        accessKeyId: process.env.AWS_ACCESS_KEY_ID,
        secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
        //region: process.env.REGION
    });
    const s3 = new aws.S3();
    var files_upload = {};
    let promiseList = new Promise(function (resolve, reject) {
        req.files.forEach(element => {
            if (element.fieldname.includes('img')) {
                var folder = 'club_images'
            } else if (element.fieldname.inlcudes('poster')) {
                var folder = 'poster_tournament'
            } else {
                var folder = 'info_tournament'
            }
            var params = {
                ACL: 'public-read',
                Bucket: process.env.AWS_BUCKET_NAME,
                Body: fs.createReadStream(element.path),
                Key: `${folder + '/' + uuidv4() + element.fieldname}`
            };
            s3.upload(params, (err, data) => {
                if (err) {
                    console.log('Error occured while trying to upload to S3 bucket', err);
                }
                if (data) {
                    fs.unlinkSync(element.path); // Empty temp folder
                    const locationUrl = data.Location;
                    files_upload[element.fieldname] = locationUrl;
                    console.log(files_upload);
                }
            });
        });
        resolve(files_upload)
    })
    Promise.all([promiseList]).then(() => {
        console.log(Object.assign(JSON.parse(req.body.values), files_upload));
        const newUser = new Tournaments(Object.assign(JSON.parse(req.body.values), files_upload));
        console.log(newUser)
        newUser
            .save()
            .then(user => {
                res.json({ message: 'User created successfully', user });
            })
            .catch(err => {
                console.log('Error occured while trying to save to DB');
            });
    })
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...