Need documentation for uploading multiple files: Uploading files (guides/advanced/file-uploading.md)
My src/services/uploads/uploads.service.js
// Initializes the `uploads` service on path `/uploads`
const createService = require('feathers-rethinkdb');
const hooks = require('./uploads.hooks');
// feathers-blob service
const blobService = require('feathers-blob');
// Here we initialize a FileSystem storage,
// but you can use feathers-blob with any other
// storage service like AWS or Google Drive.
const fs = require('fs-blob-store');
const multer = require('multer');
const multipartMiddleware = multer();
// File storage location. Folder must be created before upload.
// Example: './uploads' will be located under feathers app top level.
const blobStorage = fs('./uploads');
module.exports = function (app) {
const Model = app.get('rethinkdbClient');
const paginate = app.get('paginate');
const options = {
name: 'uploads',
Model,
paginate
};
// Upload Service with multipart support
app.use('/uploads',
// multer parses the file named 'uri'.
// Without extra params the data is
// temporarely kept in memory
multipartMiddleware.array('uri', 2),
// another middleware, this time to
// transfer the received file to feathers
function(req,res,next){
req.feathers.file = req.file;
next();
},
blobService({Model: blobStorage})
);
// Get our initialized service so that we can register hooks and filters
const service = app.service('uploads');
service.hooks(hooks);
};
My src/services/uploads/uploads.hooks.js
const dauria = require('dauria');
const { authenticate } = require('@feathersjs/authentication').hooks;
module.exports = {
before: {
all: [],
find: [],
get: [],
create: [
function(context) {
if (!context.data.uri && context.params.file){
const file = context.params.file;
const uri = dauria.getBase64DataURI(file.buffer, file.mimetype);
context.data = {uri: uri};
}
}
],
update: [],
patch: [],
remove: []
},
after: {
all: [],
find: [],
get: [],
create: [ ],
update: [],
patch: [],
remove: []
},
error: {
all: [],
find: [],
get: [],
create: [],
update: [],
patch: [],
remove: []
}
};
My dropzonejs code
Dropzone.options.myDropzone = {
paramName: function() { return 'uri'; },
uploadMultiple: true,
autoProcessQueue: false,
maxFiles: 2,
method: 'post',
init: function(){
myDropzone = this;
this.on('uploadprogress', function(file, progress){
console.log('progresss', progress);
});
}
};
I'm trying to upload several files but I get an error in the console
error: TypeError: Cannot read property 'startsWith' of undefined at Dauria.parseDataURI (/Volumes/HomeHD/Projects/Eomoe/node_modules/dauria/dauria.js:27:18) at Object.create (/Volumes/HomeHD/Projects/Eomoe/node_modules/feathers-blob/lib/index.js:87:52) at processHooks.call.then.hookObject (/Volumes/HomeHD/Projects/Eomoe/node_modules/@feathersjs/feathers/lib/hooks.js:67:27) at
at process._tickCallback (internal/process/next_tick.js:188:7)
P.S. multipartMiddleware.single('uri'), everything works well with one file
I am facing the same problem as you are now. 2 issues in your code that I can see are:
- req.file is undefined because you use multer array so instead of req.file you should use req.files
- the same should be applied to your before hook. instead of accessing context.params.file you should access context.params.files
this is the place where I am stuck BTW.
I'm facing the sambe problem anyone could help ?
My upload.service.js
// Initializes the upload service on path /upload
const createService = require("feathers-nedb");
const createModel = require("../../models/upload.model");
const hooks = require("./upload.hooks");
const blobService = require("feathers-blob");
const fs = require("fs-blob-store");
const blobStorage = fs("./uploads");
const multer = require("multer");
const multipartMiddleware = multer();
module.exports = function() { const app = this; const Model = createModel(app); const paginate = app.get("paginate");
// Initialize our service with any options it requires app.use( "/uploads", multipartMiddleware.single("uri"), function(req, res, next) { req.feathers.file = req.file; next(); }, blobService({ Model: blobStorage }) );
// Get our initialized service so that we can register hooks and filters const service = app.service("uploads");
service.hooks(hooks); };
My upload.hooks.js const dauria = require("dauria"); module.exports = { before: { all: [], find: [ context => { console.log(context); } ], get: [], create: [ context => { if (!context.data.uri && context.params.file) { const file = context.params.file; const uri = dauria.getBase64DataURI(file.buffer, file.mimetype); context.data = { uri: uri }; } } ], update: [], patch: [], remove: [] },
after: { all: [], find: [], get: [], create: [], update: [], patch: [], remove: [] },
error: { all: [], find: [], get: [], create: [], update: [], patch: [], remove: [] } };
i'm getting this error
error: Error: Unexpected field
at makeError (C:\Desenvolvimento\uploadService\node_modules\multer\lib\make-error.js:12:13)
at wrappedFileFilter (C:\Desenvolvimento\uploadService\node_modules\multer\index.js:40:19)
at Busboy.
Uhm I'm stuck here too lol, it uploads it with no errors, but it doesn't save in storage and when debugging I don't see any files in the hook. It does work with custom express middleware... Even with a single file it doesn't save it in storage though, maybe I'll create a new issue for this if I can't solve it
Getting this too. Also I don't get why we need the
const Model = createModel(app);
const paginate = app.get("paginate");
It's never used....
Ok, got it working. It works as follows:
multer checks of the property where the file is put matches the name given to the .single() call (in this case "uri"):
app.use('/files',
// multer parses the file named 'uri'.
// Without extra params the data is
// temporarely kept in memory
multipartMiddleware.single('uri'),
// another middleware, this time to
// transfer the received file to feathers
function (req, res, next) {
debug('multi-middleware', req);
req.feathers.file = req.file;
next();
},
blobService({ Model: blobStorage })
);
This check is here inside multer:

When you set all this up correctly you can post a file via Postman:

See the use of "uri" in the 2 spots.
The "Unexpected field" string is the LIMIT_UNEXPECTED_FILE const.