This question already has an answer here:
How to POST binary files with AngularJS (with upload DEMO)
(1 answer)
Closed 3 years ago.
I have some problem on FormData of Angular.js
My code is this:
angular
.module("appFoco", [])
.directive('fileModel', ['$parse', function ($parse) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
var model = $parse(attrs.fileModel);
var modelSetter = model.assign;
element.bind('change', function(){
scope.$apply(function(){
modelSetter(scope, element[0].files[0]);
});
});
}
};
}])
.service('fileUpload', ['$http', function ($http) {
this.uploadFileToUrl = function(file) {
var fd = new FormData();
fd.append('file', file);
$http.post('/send/sendPlanilha', fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
.success(function() {
})
.error(function() {
});
}
}])
.controller("LoginFormPDF",['$scope','fileUpload', function($scope,fileUpload){
$scope.sendPlanilha = function(){
console.log($scope.email, $scope.nome);
var file = $scope.myFile;
console.dir(file);
$scope.usuario = {"usuarioEmail" : $scope.email, "usuarioNome" : $scope.nome}
fileUpload.uploadFileToUrl(file);
}
}]);
When I do the $http.post, the fd on fd.append is empty, and I do not know why this is happend. On fd will have a file like arq.xls .
I already saw many kins of tutorials and I did not find a solution.
The backend code is in NodeJs, so I need to take a file on fd.append and send to $http.post for a another function on Nodejs, this function is below:
app.post('/send/sendPlanilha', function(req, res, next){}
So, my question is, Why fd on fd.append is empty? And how I can fix this?
It is more efficient to send the file directly:
app.service('fileUpload', ['$http', function ($http) {
this.uploadFileToUrl = function(file) {
̶v̶a̶r̶ ̶f̶d̶ ̶=̶ ̶n̶e̶w̶ ̶F̶o̶r̶m̶D̶a̶t̶a̶(̶)̶;̶
̶f̶d̶.̶a̶p̶p̶e̶n̶d̶(̶'̶f̶i̶l̶e̶'̶,̶ ̶f̶i̶l̶e̶)̶;̶
̶$̶h̶t̶t̶p̶.̶p̶o̶s̶t̶(̶'̶/̶s̶e̶n̶d̶/̶s̶e̶n̶d̶P̶l̶a̶n̶i̶l̶h̶a̶'̶,̶ ̶f̶d̶,̶ ̶{̶
return $http.post('/send/sendPlanilha', file, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
}
}])
The base64 encoding of Content-Type: multipart/form-data adds an extra 33% overhead. And the backend then needs to decode the base64 data.
Related
I tried sending json data and a single file using angular formdata but its not working. I don't receive json from my server. Here is my code with angularjs
angular
.module('app')
.directive('fileModel', ['$parse', function ($parse) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
var model = $parse(attrs.fileModel);
var modelSetter = model.assign;
element.bind('change', function(){
scope.$apply(function(){
modelSetter(scope, element[0].files[0]);
});
});
}
};
}]);
angular
.module('BossApp')
.controller('addresumeCtrl', addresumeCtrl);
function addresumeCtrl ($scope,ngDialog,$http) {
$scope.resume = {};
$scope.resume.educations = [];
$scope.resume.experiences = [];
$scope.create = function(){
var uploadUrl = "/user/add-resume";
var fd = new FormData();
for(var key in $scope.resume)
fd.append(key, $scope.resume[key]);
$http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
}).then(function (response) {
}, function (error) {
});
};
}
How to fix this?
I am going with file upload issue, in which I am using angular in front-end and Java at backend and uploading image on S3 bucket. I think there is no issue in java code because when I am using this upload URL on postman it is going well, I am Attaching Postman screenshot to showcase how it is working fine
Here is My AngularJS Controller as follows :
contactUs.controller('contactController', ['$scope','$http',
function($scope,$http) { $scope.uploadFile = function(){
var file = $scope.myFile;
console.log('file is ' );
console.dir(file);
var uploadUrl = "uploadURL";
var fd = new FormData(file);
fd.append('files', file);
$http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers: {'Content-Type': 'multipart/form-data',
'Authorization': 'Basic QHN0cmlrZXIwNzoxMjM0NTY='}
})
.success(function(response){
console.log(response);
})
.error(function(error){
console.log(error);
});
};
}]);
Here is My AngularJS Directive as follows :
contactUs.directive('fileModel', ['$parse', function ($parse) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
var model = $parse(attrs.fileModel);
var modelSetter = model.assign;
console.log(model);
console.log(modelSetter);
element.bind('change', function(){
scope.$apply(function(){
modelSetter(scope, element[0].files[0]);
});
});
}
};
}]);
The HTML is as follows :
<input type = "file" name="files" file-model = "myFile"/>
<button ng-click = "uploadFile()">upload me</button>
The Java controller is as follows :
#Path("/upload")
#POST
#Consumes(MediaType.MULTIPART_FORM_DATA)
#Produces("application/text")
public Response uploadFile(#FormDataParam("files") List<FormDataBodyPart> bodyParts,#FormDataParam("files") FormDataContentDisposition fileDispositions) {
/* Save multiple files */
BodyPartEntity bodyPartEntity = null;
String fileName = null;
for (int i = 0; i < bodyParts.size(); i++) {
bodyPartEntity = (BodyPartEntity) bodyParts.get(i).getEntity();
fileName = bodyParts.get(i).getContentDisposition().getFileName();
s3Wrapper.upload(bodyPartEntity.getInputStream(), fileName);
}
String message= "File successfully uploaded !!";
return Response.ok(message).build();
}
The Error I am getting with the AngularJS is below :
400 - Bad Request
1) To POST File data, You don't need to provide content-type as Multi part/form-data. Because It understand data type automatically. So just pass headers: {'Content-Type': undefined}.
2) As you show in your postman, key is files then If you are providing name="files" and fd.append("files",file), It will not process as files key is on both side. So, Remove name="files" from HTML and process the upload file then.
Usually I use following with $http to send multi-part form data. Please try this.
var formdata = new FormData();
formdata.append('files', file);
return $http.post(uploadUrl, formdata, { transformRequest: angular.identity, headers: {'Content-Type': undefined} });
I am working on a project that uses Angularjs for the FrontEnd and Java Webservices in the backend. I am trying to upload and send an Image through JSON.
The Images when uploaded, generates a blob url ( blob:http://localhost/a34ac19f-3320-4cdf-b30f-e1b0a0e7a745 ) in src. How can I read it and convert it to Base64 or other types that can be sent through JSON?
First of all add this custom directory right below your controller :
app.directive('fileModel', ['$parse', function ($parse) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
var model = $parse(attrs.fileModel);
var modelSetter = model.assign;
element.bind('change', function () {
scope.$apply(function () {
modelSetter(scope, element[0].files[0]);
});
});
}
};
}]);
Then in you view use it like this :
<input type = "file" name="files" file-model = "myFile"/>
In your controller function when youf form will submitted :
Do it like this :
$scope.formSubmit = function(){
var file = $scope.myFile;
var fd = new FormData();
fd.append('profilepic', file);
fd.append('action', 'add');
$http.post('yourjavafile', fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
}).success(function (response) {
if (response) {
} else {
}
});;
}
I have the following HTML.
<form >
<input type="file" file-model="myFile"/>
<button ng-click="uploadFile()">upload me</button>
</form>
And inside controller I have following function
$scope.uploadFile = function() {
var file = $scope.myFile; //when I try console.log(file...it says undefined)
var fd = new FormData();
fd.append('file', file);
$http.post("url", fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined},
transformResponse: [function (data) {
return data;
}]
}).then(function (result) {
console.log(result.data);
})
}
the Directives I have is
.directive('fileModel', ['$parse', function ($parse) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
var model = $parse(attrs.fileModel);
var modelSetter = model.assign;
element.bind('change', function(){
scope.$apply(function(){
modelSetter(scope, element[0].files[0]);
});
});
}
};
}]);
For some reason, I am not getting the file value. On console.log() I am receiving undefined. FYI, I am just trying to grab a file. Is there something wrong in my code?
I came to that conclusion because it seems to have passing undefined to server from browser's developer tool. The screen-grab is as follows.
The problem was non binding issue with files. Angular has no support for that yet. It was solved with the solution provided here.
AngularJs: How to check for changes in file input fields?
This worked for me:
<div>
<input id="imageList" name="imageList" type="file" file-model="myFile">
</div>
I also had a json object to send with the form:
$scope.saveForm = function () {
var formData = new FormData();
var file = $scope.myFile;
formData.append("file", file);
var req = {
url: '/upload',
method: 'POST',
headers: {'Content-Type': undefined},
data: formData,
transformRequest: function (data, headersGetterFunction) {
return data;
}
};
Angular suggests setting 'Content-Type' header to undefined (https://docs.angularjs.org/api/ng/service/$http) so that the browser can pick up the file data and supply the correct Content-Type header.
But even when I upload a PDF, the content-type is set to 'text/plain;charset=UTF-8'. I want the content-type to be set to multipart, because this is what the backend expects, but how can I make this happen, if the browser is responsible for setting the content-type?
I have also tried this post's tactic but to no avail. I have also tried using Dropzone.js with the same result.
Here's the code for the request itself:
uploadFile: function(token, baseurl, projectname, filename, file) {
var dataUpload= {
method: 'PUT',
url: baseurl + '/projects/' + projectname + '/files/' + filename,
transformRequest: angular.identity,
headers: {
'Authorization': 'bearer ' + token,
'Accept': "application/json",
'Content-Type': undefined
},
data: {
'files': file
}
};
return dataUpload;
}
Below I am including the code from the post previously linked which is supposed to work but when I used it with my own url the same thing happens: the browser sets Content-Type to 'text/plain;charset=UTF-8' and I get a 415 error from the backend. How? Why? Any help (including workarounds for the backend) would be extremely appreciated. I've been working on this for days.
The JavaScript:
var myApp = angular.module('myApp', []);
myApp.directive('fileModel', ['$parse', function ($parse) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
var model = $parse(attrs.fileModel);
var modelSetter = model.assign;
element.bind('change', function(){
scope.$apply(function(){
modelSetter(scope, element[0].files[0]);
});
});
}
};
}]);
myApp.service('fileUpload', ['$http', function ($http) {
this.uploadFileToUrl = function(file, uploadUrl){
var fd = new FormData();
fd.append('file', file);
$http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
.success(function(){
})
.error(function(){
});
}
}]);
myApp.controller('myCtrl', ['$scope', 'fileUpload', function($scope, fileUpload){
$scope.uploadFile = function(){
var file = $scope.myFile;
console.log('file is ' );
console.dir(file);
var uploadUrl = "/fileUpload";
fileUpload.uploadFileToUrl(file, uploadUrl);
};
}]);
The HTML:
<div ng-controller = "myCtrl">
<input type="file" file-model="myFile"/>
<button ng-click="uploadFile()">upload me</button>
</div>
I guess it's too late to answer this but in case someone came across with the same problem.
The error in your code is here:
data: {
'files': file
}
Your form data object already has the information of the field your backend is expecting so, you need to change that line for:
data: file
If you've created the FormData object manually you'll probably have something like this:
var fd = new FormData();
fd.append("files", $scope.file);