Reputation: 9173
I have an interesting problem. I'm trying to upload a form by way of
<form enctype="multipart/form-data" action="/myendpoint/:id">
<input type="hidden" name="data" value="mydata" />
<input type="file" name="formname" />
</form>
... and my remote method call:
Patient.uploadVideo = function(id, mydata, cb) {
console.log(mydata);
return cb(null, { id: 123 });
};
MyModel.remoteMethod(
'uploadVideo',
{
http: {path: '/:id/recording/:recordingid/videos', verb: 'post'},
accepts: [
{arg: 'id', type: 'string', required: true},
{arg: 'mydata', type: 'object', 'http': {source: 'body'}},
]
}
);
Unfortunately the body is coming in as blank
How do I get the form data? I modified server/datasources.json to include
"storage": {
"name": "storage",
"connector": "loopback-component-storage",
"provider": "filesystem",
"root": "./server/storage"
}
Still nothing.
Thanks
Upvotes: 3
Views: 843
Reputation: 153
Thanks for the guidance. I got file upload working with loopback and angular 2, which considering how small the documentation is for those two is a huge feat. A few expansions:
In MyModel.myFunction = function(req, res, options, cb) {
, the options
is not strictly necessary. You can just pass any desired options as a "property" of the formData object that one would likely pass into req
object. In your example, if options
is not passed into the function, but only the formData, then cb
will not be assigned and will bork the entire call.
If anyone wants to know how I achieved this, the main calls are:
upload-test.component.ts
let file = event.srcElement.files[0];
let formData:FormData = new FormData();
this.forumPostService.uploadFile(formData).subscribe(
response => {
console.log(response);
}
);
upload-test.service.ts
uploadFile(formData: FormData) {
//LEAVE HEADERS BLANK. LOOPBACK CALL BORKS IF ASSIGNED!
let headers = new Headers();
return this.http
.post('http://apiUrl/myModel/uploadTest',
formData,
{headers: headers})
.map((response: Response) => {
return response.json();
});
}
"formData", which holds the file, is passed into "req" in http request to loopback API
uploadTest.js
myModel.uploadTest = function(req, res, callback) {
var storage = require('loopback-component-storage');
//"root:'/'" will point to home drive, e.g. 'C://'
var storageService = storage.StorageService({provider:'filesystem', root:'/'});
/*"upload" will give e.g. 'C://upload', make sure this folder exists,
it wont create it for you*/
storageService.upload(req, res, { container: 'upload'}, function(err, data) {
if (err) {
callback(err);
}
else {
console.log(data.files.file[0]);
callback(null, data.files.file[0]);
}
});
}
PostSections.remoteMethod(
'uploadTest',{
accepts: [
{arg: 'req', type: 'object', 'http': {source: 'req'}},
{arg: 'res', type: 'object', 'http': {source: 'res'}}
],
returns: [
{ arg: 'Result', type: 'object' }
],
http: { path: '/uploadTest', verb: 'post'}
}
);
Upvotes: 0
Reputation: 9173
So unfortunately the documentation is very limited when discussing how to upload files. There is one reference to the module "loopback-component-storage", one has to tear into it in order to find this diamond in the rough.
var storage = require('loopback-component-storage');
MyModel.myFunction = function(req, res, options, cb) {
var storage = require('loopback-component-storage');
var storageService = storage.StorageService({provider: 'filesystem', root: '/tmp'});
storageService.upload(req, res, { container: 'upload' }, function(err, data) {
console.log(data); // this provides a nice object with all of the variables and data wrt the file that was uploaded
/// ..etc
});
};
MyModel.remoteMethod(
'myFunction',
{
http: {path: '/mypath', verb: 'post'},
accepts: [
{arg: 'req', type: 'object', 'http': {source: 'req'}},
{arg: 'res', type: 'object', 'http': {source: 'res'}}
],
returns: {arg: 'something', type: 'object'}
}
);
You can find the documentation for StorageService here
Upvotes: 5