I am trying to use ng-file-upload to upload multiple files at the same time to my grails controller action. However, I can't figure out how to get a hold of the files that are being uploaded to the action.
Here is my JS code:
app.controller('MyCtrl', ['$scope', 'Upload', '$timeout', function ($scope, Upload, $timeout) {
$scope.uploadFiles = function (files) {
$scope.files = files;
if (files && files.length) {
Upload.upload({
url: 'http://localhost:8080/classifydemo/request/create',
data: {
files: files
}
}).then(function (response) {
$timeout(function () {
$scope.result = response.data;
});
}, function (response) {
if (response.status > 0) {
$scope.errorMsg = response.status + ': ' + response.data;
}
}, function (evt) {
$scope.progress =
Math.min(100, parseInt(100.0 * evt.loaded / evt.total));
});
}
};
}]);
And my grails action is below:
class RequestController {
def create() {
request.headerNames.each{
println it
}
println params
println request.getFile("file")
render "test"
}
}
The above code fails on request.getFile.
Question
How can I get a hold of the files that are being uploaded to the controller so that I can process them in a loop.
Since you have the possibility of multiple files you should use:
request.fileNames.each {
MultipartFile file = request.getFile(it)
// do whatever you want with the file
}
Related
I'm using ng-file-upload to upload multiple files to the server. The server responds back after a while (~10 seconds). In this time I would like to show a spinner on the screen.
I'm currently showing a spinner like this
<img src="http://www.ajaxload.info/cache/ff/ff/ff/00/00/00/8-0.gif"/>
but it is there permanently. How can I make it so that it appears only for the time until the response is back from the server?
my upload code follows:
Upload.upload({
url: 'http://localhost:8080/myapp',
data: {
files: files
}
}).then(function (response) {
$timeout(function () {
$scope.result = response.data;
$scope.text = response.data.text;
$scope.notext = response.data.notext;
});
}, function (response) {
if (response.status > 0) {
$scope.errorMsg = response.status + ': ' + response.data;
}
}, function (evt) {
$scope.progress =
Math.min(100, parseInt(100.0 * evt.loaded / evt.total));
});
If I got you right...
html:
<img src="http://www.ajaxload.info/cache/ff/ff/ff/00/00/00/8-0.gif" ng-hide="loaderHidden"/>
js:
$scope.loaderHidden = true;
function upload() {
$scope.loaderHidden = false;
Upload.upload({
url: 'http://localhost:8080/myapp',
data: {
files: files
}
}).then(function (response) {
$timeout(function () {
$scope.loaderHidden = true;
$scope.result = response.data;
$scope.text = response.data.text;
$scope.notext = response.data.notext;
});
}, function (response) {
if (response.status > 0) {
$scope.errorMsg = response.status + ': ' + response.data;
}
}, function (evt) {
$scope.progress =
Math.min(100, parseInt(100.0 * evt.loaded / evt.total));
});
}
then just call upload()
I don't have much front-end experience, so please bear with me.
I have a local Angular app in browser (no back-end) and I want to upload a JSON file so that I can show the uploaded data on graphs. Since I don't know if I can just fs.readFile from Angular, I've chosen ng-file-upload to load the file in a nice way (from the file browser). Let me know if it isn't the right tool, though...
So I've copied the code from the official JS Fiddle on the repo. Had to modify it a bit to allow me upload anything -- remove validations.
var app = angular.module('app', ['ngFileUpload']);
app.controller('fileUploader', ['$scope', 'Upload', '$timeout', function ($scope, Upload, $timeout) {
$scope.uploadFiles = function(file, errFiles) {
$scope.f = file;
$scope.errFile = errFiles && errFiles[0];
if (file) {
file.upload = Upload.upload({
url: 'https://angular-file-upload-cors-srv.appspot.com/upload',
data: {file: file}
});
file.upload.then(function (response) {
$timeout(function () { // don't know why this timeout
$scope.fileReady = true;
file.result = response.data;
// can't figure out what to do with this!!!
console.log('response.data:\n', JSON.stringify(response.data.result, null, 2));
});
}, function (response) {
if (response.status > 0)
$scope.fileError = response.status + ': ' + response.data;
});
}
};
}]);
The response comes out as an object I can't do much with:
[
{
"fieldName": "file",
"name": "my-awesome-data.json",
"size": "364077"
}
]
How do I get the actual data that was uploaded / parse the JSON file?
Try to get the file content using $http.get like:
$http.get(response.data).success(function(data) {
console.log(data);
});
I have a code that uploads documents in the controller, I wanted it to be moved to a service, so that other controllers can consume it.
"use strict";
angular.module('myApp')
.service('uploadDocumentService', ['Upload', function (Upload) {
this.UploadDocument = function ($file, data) {
Upload.upload({
url: '/uploadDocuments',
file: $file,
data: data
}).progress(function (evt) {
var progressReport = {};
progressReport.progressVisible = true;
progressReport.percentage = Math.round(evt.loaded / evt.total * 100);
return progressReport;
}).success(function (data, status, headers, config) {
var fileUploaded = {};
fileUploaded.id = data.id;
fileUploaded.name = data.fileName;
return fileUploaded;
});
}
}]);
I am unable to capture the .progress event in my controller
uploadDocumentService.UploadDocument($file, 'Path')
.progress(function (progressReport) {
//Some code
}).success(function (data) {
//Some code
});
Keep getting the error Cannot read property 'progress' of undefined
at m.$scope.uploadDocuments
Any tips on how to solve this problem, do I need to register the progress event in the service?
Controller code
"use strict";
angular.module('myApp')
.controller('controller', ['$scope', '$http', 'Upload', 'uploadDocumentService', function ($scope, $http, Upload, uploadDocumentService) {
$scope.uploadDocuments = function ($files) {
$scope.progressVisible = false;
for (var i = 0; i < $files.length; i++) {
var $file = $files[i];
uploadDocumentService.UploadDocument($file, 'path')
.progress(function (evt) {
$scope.progressVisible = true;
$scope.percentage = Math.round(evt.loaded / evt.total * 100);
}).success(function (data) {
var fileUploaded = {};
fileUploaded.id = data.id;
fileUploaded.name = data.fileName;
$scope.filesUploaded.push(fileUploaded);
$scope.isFileUploaded = true;
});
}]);
A colleague pointed out the mistake, the fix is as below, return was missing in the statement Upload.upload
"use strict";
angular.module('myApp')
.service('uploadDocumentService', ['Upload', function (Upload) {
this.UploadDocument = function ($file, data) {
return Upload.upload({
url: '/uploadDocuments',
file: $file,
data: data
}).progress(function (evt) {
}).success(function (data, status, headers, config) {
});
}
}]);
To achieve your expected result,add uploadDocumentService param in your controller function.
angular.module('myApp').controller("controller", function($scope, uploadDocumentService)
With this directive: ng-file-upload
How can I upload sequentially (in order, queue) multiple files one by one? I'm thinking about chained promises, but I don't know how can I combine promises and directive.
This is an example to upload multiple files, but all at the same time and not in order.
This is my code:
for (var i = 0; i < files.length; i++) {
Upload.upload({
url: config.base+'/upload/',
data: {
file: files[i],
}
}).then(function (response) {
vm.reloadImatges();
vm.upload.progress=0;
vm.upload.files--;
}, function (resp) {
}, function (evt) {
vm.upload.progress = parseInt(100.0 * evt.loaded / evt.total);
});
}
I found a solution, maybe not the best, but it works
http://jsfiddle.net/erLax2fm/2/
Code below:
var doSomething = function (index) {
var defer = $q.defer();
Upload.upload({
url: url: config.base+'/upload/',
data: {
file: objects[index]
}
}).then(function (response) {
objects[index].processed = true;
if (objects[++index]) {
defer.resolve(index);
} else {
defer.reject();
}
}, function (response) {
}, function (evt) {
vm.upload.progress = parseInt(100.0 * evt.loaded / evt.total);
});
defer.promise.then(doSomething);
};
doSomething(0);
I want to implement file uploading in my web application, I am using angular.js on client side and spring mvc on server side.
I managed to get single file upload and multiple file upload working by using https://github.com/danialfarid/angular-file-upload. The thing is, when I upload multiple files each one of them is coming to me as separate request (which is obvious event after reading example code):
//inject angular file upload directives and service.
angular.module('myApp', ['angularFileUpload']);
var MyCtrl = [ '$scope', '$upload', function($scope, $upload) {
$scope.onFileSelect = function($files) {
//$files: an array of files selected, each file has name, size, and type.
for (var i = 0; i < $files.length; i++) {
var $file = $files[i];
$scope.upload = $upload.upload({
url: 'server/upload/url', //upload.php script, node.js route, or servlet url
// method: POST or PUT,
// headers: {'headerKey': 'headerValue'}, withCredential: true,
data: {myObj: $scope.myModelObj},
file: $file,
//(optional) set 'Content-Desposition' formData name for file
//fileFormDataName: myFile,
progress: function(evt) {
console.log('percent: ' + parseInt(100.0 * evt.loaded / evt.total));
}
}).success(function(data, status, headers, config) {
// file is uploaded successfully
console.log(data);
})
//.error(...).then(...);
}
}
}];
there is an iteration through all the files.
Now I am wondering if it is possible to somehow upload multiple files as one, single request.
on spring controller side create
#RequestMapping(value = "/upload", method = RequestMethod.POST)
public String save(#ModelAttribute("filesForm") FileUploadForm filesForm) {
List<MultipartFile> files = filesForm.getFiles();
//do something
}
public class FileUploadForm
{
private List<MultipartFile> files;
// geters and setters ...
}
on client side upload service
return {
send: function(files) {
var data = new FormData(),
xhr = new XMLHttpRequest();
xhr.onloadstart = function() {
console.log('Factory: upload started: ', file.name);
$rootScope.$emit('upload:loadstart', xhr);
};
xhr.onerror = function(e) {
$rootScope.$emit('upload:error', e);
};
xhr.onreadystatechange = function(e)
{
if (xhr.readyState === 4 && xhr.status === 201)
{
$rootScope.$emit('upload:succes',e, xhr, file.name ,file.type);
}
};
angular.forEach(files, function(f) {
data.append('files', f, f.name);
});
xhr.open('POST', '../upload');
xhr.send(data);
}
};