var upload = this.s3.upload(params) TypeError: this.s3.upload is not a function - multer-s3

I am trying to upload a file to S3 using multer s3.However, it constantly fails.
aws.config.update({
secretAccessKey: 'key',
accessKeyId: 'secret',
});
var s3 = new aws.S3()
var upload = multer({
storage: multerS3({
s3: s3,
bucket: 'pdsfiles',
metadata: function (req, file, cb) {
cb(null, {fieldName: file.fieldname});
},
key: function (req, file, cb) {
cb(null, Date.now().toString())
}
})
})
This is what the error looks like:
TypeError: this.s3.upload is not a function
at S3Storage. (/home/simran/Downloads/NODE-BACKEND/node_modules/multer-s3/index.js:172:26)
at /home/simran/Downloads/NODE-BACKEND/node_modules/multer-s3/index.js:58:10
at S3Storage.getContentType (/home/simran/Downloads/NODE-BACKEND/node_modules/multer-s3/index.js:8:5)
at /home/simran/Downloads/NODE-BACKEND/node_modules/multer-s3/index.js:55:13
at end (/home/simran/Downloads/NODE-BACKEND/node_modules/run-parallel/index.js:16:15)
at _combinedTickCallback (internal/process/next_tick.js:73:7)
at process._tickDomainCallback (internal/process/next_tick.js:128:9)
Call:
router.put('/updatePatternGrading/:pattern_number', upload.any(), function(req, res){
console.log("request obj after manipulation", req.files);
callAPI(req, res, fn.bind(apiObj, 'updatePatternGrading'));
})
Why do I get this ?

Related

Multer-s3-transform with Sharp middleware in Express JS route, uploads correctly, but never calls next

I'm using multer-s3-transform to resize my image upload beore uploading to S3. Using Sharp for the resize. The transform does work fine, the image is resized and uploaded to S3 bucket, I can see the file in the bucket. However, the uploadToS3.single('profilePic') middleware never continues to next route which is end route.
What am I doing wrong?
exports.uploadToS3 = multer({
storage: multerS3({
s3: s3,
bucket: S3_BUCKET,
acl: 'public-read',
contentType: multerS3.AUTO_CONTENT_TYPE,
fileFilter: allowOnlyImages,
limits: {
fileSize: 1024 * 250 // We are allowing only 250K
},
shouldTransform: (req, file, cb) => {
// Is this an image file type?
cb(null, /^image/i.test(file.mimetype));
},
transforms: [{
id: 'thumbnail',
key: (req, file, cb) => {
const fn = `${S3_PROFILE_PICS}/${req.body.handle}/${createFilename(req, file)}`;
//console.log('transforms key fn: ', fn);
cb(null, fn);
},
transform: (req, file, cb) => {
//console.log('transform: ', file.originalname);
// Perform desired transformations
const width = parseInt(PROFILE_PIC_W);
const height = parseInt(PROFILE_PIC_H);
cb(null, sharp()
.resize(width, height)
.toFormat('jpeg')
);
}
}]
})
});
Route...
router.post('/register', uploadToS3.single('profilePic'), async (req, res) => {
...
...
});
It's something about the transform and/or Sharp. If I remove the Sharp transform and just upload the incoming image to S3, everything works fine.
Try this to see it work:
router.post('/register', uploadToS3.single('profilePic'), async (req, res, next) => {
...
...
});

Unexpected end of multipart data nodejs multer s3

iam trying to upload image in s3 this is my code
const upload = require('../services/file_upload');
const singleUpload = upload.single('image');
module.exports.uploadImage = (req,res) => {
singleUpload(req, res, function (err) {
if (err) {
console.log(err);
return res.status(401).send({ errors: [{ title: 'File Upload Error', detail: err}] });
}
console.log(res);
return res.json({ 'imageUrl': req.file.location });
});
}
FileUpload.js
const aws = require('aws-sdk');
const multer = require('multer');
const multerS3 = require('multer-s3');
const s3 = new aws.S3();
const fileFilter = (req, file, cb) => {
if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png') {
cb(null, true)
} else {
cb(new Error('Invalid Mime Type, only JPEG and PNG'), false);
}
}
const upload = multer({
fileFilter,
storage: multerS3({
s3,
bucket: 'image-bucket',
acl: 'public-read',
contentType: multerS3.AUTO_CONTENT_TYPE,
metadata: function (req, file, cb) {
cb(null, {fieldName: 'TESTING_META_DATA!'});
},
key: function (req, file, cb) {
cb(null,"category_"+Date.now().toString()+".png")
}
})
})
module.exports = upload;
I tried to test api with postmanin serverless local it is giving this error
Error: Unexpected end of multipart data
at D:\Flutter\aws\mishpix_web\node_modules\dicer\lib\Dicer.js:62:28
at process._tickCallback (internal/process/next_tick.js:61:11) storageErrors: []
After deploying online. i tried the api. the file is uploaded in server but its a broken
Are you using aws-serverless-express. aws-serverless-express will forward original request to Buffer as utf8 encoding. So multipart data will be lost or error. I am not sure why.
So, I change aws-serverless-express to aws-serverless-express-binary and everything worked.
yarn add aws-serverless-express-binary
Hope this help!

Multer, Multer-s3 not calling callbacks for dynamic key naming

I'm trying to pipe a file that I send with FilePond for React, get with on my expressjs and upload to s3 with multer and multer-s3. I have seen tutorials that specify that the best way to name the files dynamically is to declare a callback on the key but if I do not set a value directly, it simply ignores is and the whole multer middleware sends a success message.
Here is what I'm doing in express:
const app = express();
app.use(bodyParser.urlencoded({ extended: true }))
var upload = multer({
storage: multerS3({
s3: s3,
bucket: aws_bucket_name,
ACL: "public-read",
key: (req, file, cb) => {
console.log("This never gets called");
console.log(req.body);
console.log(file);
cb(null, avatars/${req.params.uid});
}
})
});
app.post('/avatar/:uid', upload.single('file'), async (req, res, next) => {
console.log("this gets called")
res.send("uploaded")
});
I'm using ES6, and am doing exactly as the documentation suggests. Any ideas why this might not be working?
Thanks!

Multer-s3 dynamic s3 instance

I'm trying to upload files to my s3 bucket, using multer and multer-s3 for Nodejs. The problem that I have now is that I want to set up my s3 instance dynamically because the s3 account and the bucket depend on my user settings.
I have the following code:
My uploader
var uploader = multer({
storage: multerS3({
s3: function(req, file, cb){
cb(null, new AWS.S3({
// my s3 settings from req.body or getting directly from my db
}))
},
bucket: function (req, file, cb){
cb(null, req.body.bucket)
},
metadata: function (req, file, cb) {
cb(null, {
fieldName: file.fieldname
});
},
key: function (req, file, cb) {
console.log(`Key is ${req.body.prefix + file.originalname}`);
cb(null, req.body.prefix + file.originalname)
}
})
}).single('file');
api.post('/upload', uploader, function (req, res, next) {
if (err)
return res.status(500).json({ message: err });
res.status(200).json({
message: 'uploaded'
});
});
The problem is that multer-s3 doesn't allow a function for s3 option as parameter but an s3 object instead.
How can I aproach this?

uploading large video files to s3 with express.js

i'm uploading media files to s3 with express and multer-s3. it's working fine if i upload files less than 10 mb.
if i upload larger than 7mb( i tested for. if i upload around 30mb it'll fail), it gives error.cannot determine length of string
I'm uploading .mp4 file
Error Message
Exception has occurred: Error
Error: Cannot determine length of [object Object]
at byteLength (projectpath/node_modules/aws-sdk/lib/util.js:200:26)
at ManagedUpload.adjustTotalBytes (projectpath/node_modules/aws-sdk/lib/s3/managed_upload.js:299:25)
at ManagedUpload.configure (projectpath/node_modules/aws-sdk/lib/s3/managed_upload.js:122:10)
at new ManagedUpload (projectpath/node_modules/aws-sdk/lib/s3/managed_upload.js:93:10)
at features.constructor.upload (projectpath/node_modules/aws-sdk/lib/services/s3.js:1087:20)
at S3Storage.<anonymous> (projectpath/node_modules/multer-s3/index.js:182:26)
at projectpath/node_modules/multer-s3/index.js:68:10
at FileStream.<anonymous> (projectpath/node_modules/multer-s3/index.js:47:5)
at Object.onceWrapper (events.js:286:20)
at FileStream.emit (events.js:198:13)
at FileStream.EventEmitter.emit (domain.js:448:20)
at FileStream.Readable.read (_stream_readable.js:491:10)
at flow (_stream_readable.js:957:34)
at resume_ (_stream_readable.js:938:3)
at process._tickCallback (internal/process/next_tick.js:63:19)
my code
Body parser config
app.use(bodyparser.urlencoded({ extended: true, limit: '1024mb' }));
app.use(bodyparser.json({}));
file route
router.route('/faqvideoupload')
.post(faqFileUpload.array('files', 1), uploadFileHandler)
faqFileUpload
module.exports.faqFileUpload = multer({
storage: multerS3({
s3: s3,
acl: 'public-read',
bucket: process.env.BUCKET_NAME,
contentDisposition: 'inline',
// contentLength: 1 * 1024 * 1024 * 1024,
contentType: multerS3.AUTO_CONTENT_TYPE,
metadata: function (req, file, cb) {
cb(null, { fieldName: file.fieldname, });
},
key: function (req, file, cb) {
// console.log(file, 23244324)
cb(null, `faqs/videos/filename}`)
}
})
})
uploadFileHandler
async function uploadFileHandler(req, res){
try {
let files = req.files.map((img)=> {
return {
key : img.key, location : img.location, type: img.mimetype
}
})
return res.json({
success : true,
files
})
} catch (error) {
return res.json({
success: false,
message: error.message
})
}
}
do i need to change any setting in s3 bucket itself?
i also read that i have to contentLength but this also not work.
i'm using t2.micro ec2 with eb