Here is my code to upload file to server on input change
$scope.uploadImage = function (f) {
$http.post('/art',{'image':f},{headers: {'Content-Type': undefined}}).then(function (response) {
console.log(response);
});
}
but i will get empty files in server however i check my serverside code with normal fileupload it works fine without any problem
Serverside
//get empty in angular upload
console.log(req.file('image'));
req.file('image').upload({
// don't allow the total upload size to exceed ~10MB
maxBytes: 10000000
},function whenDone(err, uploadedFiles) {
return res.json({
'status':uploadedFiles
})
});
HTML
<input type="file" ng-model="art.artImage" onchange="angular.element(this).scope().uploadImage(this.files)" name="artImage" id="artImage">
I believe its problem with content-type in angular http post request
when the input type is file file will not attach the model. You need a workaround like this.
.directive("fileread", [function () {
return {
scope: {
fileread: "="
},
link: function (scope, element, attributes) {
element.bind("change", function (changeEvent) {
var reader = new FileReader();
reader.onload = function (loadEvent) {
scope.$apply(function () {
scope.fileread = loadEvent.target.result;
});
}
reader.readAsDataURL(changeEvent.target.files[0]);
});
}
}
}]);
change the input like
<input type="file" fileread="art.artImage" onchange="angular.element(this).scope().uploadImage(this.files)"
name="artImage" id="artImage">
use the multipart header in your request
$http.post('/art', {
'image': art.artImage
}, {
transformRequest: angular.identity,
headers: {
'Content-Type': "multipart/form-data"
}
})
Use ng-fileUpload lib for angularjs
My HTML
<form method="post" enctype="multipart/form-data" ng-controller="commentCtrl" name="form">
<img src="source/assets/images/icons/icofileattached.png" class="attachmentpng-height" ngf-select="uploadFiles($file)" ng-model="files"/>
<md-button type="submit" class="md-raised custom-submit-button" ng-click="MakeComments()"> SUBMIT </md-button>
</form>
My Controller code
$scope.uploadFiles = function(file) {
console.log(file);
$scope.fileData = file;
var fd = new FormData();
fd.append('file', file);
Restangular.one('/api/files/end points').withHttpConfig({transformRequest: angular.identity})
.customPOST(fd, '', undefined, {'Content-Type': undefined})
};
Please try this , avoid using onload in HTML tag for file :
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
</head>
<body ng-app = "myApp">
<div ng-controller = "myCtrl">
<input type = "file" file-model = "myFile"/>
<button ng-click = "uploadFile()">upload me</button>
</div>
<script>
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(){
alert("Done");
})
.error(function(){
alert("Sorry");
});
}
}]);
myApp.controller('myCtrl', ['$scope', 'fileUpload', function($scope, fileUpload){
$scope.uploadFile = function(){
var file = $scope.myFile;
console.log('file is ' );
console.dir(file);
var uploadUrl = "/art";
fileUpload.uploadFileToUrl(file, uploadUrl);
};
}]);
</script>
</body>
</html>
Related
I have a form with two input text and one upload. I have to send it to the server but I have some problem concatenating the file with the text. The server expects this answer:
"title=first_input" "text=second_input" "file=my_file.pdf"
This is the html:
<input type="text" ng-model="title">
<input type="text" ng-model="text">
<input type="file" file-model="myFile"/>
<button ng-click="send()">
This is the Controller:
$scope.title = null;
$scope.text = null;
$scope.send = function(){
var file = $scope.myFile;
var uploadUrl = 'my_url';
blockUI.start();
Add.uploadFileToUrl(file, $scope.newPost.title, $scope.newPost.text, uploadUrl);
};
This is the Directive fileModel:
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]);
});
});
}
};
And this is the Service which call the server:
this.uploadFileToUrl = function(file, title, text, uploadUrl){
var fd = new FormData();
fd.append('file', file);
var obj = {
title: title,
text: text,
file: fd
};
var newObj = JSON.stringify(obj);
$http.post(uploadUrl, newObj, {
transformRequest: angular.identity,
headers: {'Content-Type': 'multipart/form-data'}
})
.success(function(){
blockUI.stop();
})
.error(function(error){
toaster.pop('error', 'Errore', error);
});
}
If I try to send, I get Error 400, and the response is: Multipart form parse error - Invalid boundary in multipart: None.
The Payload of Request is: {"title":"sadf","text":"sdfsadf","file":{}}
Don't serialize FormData with POSTing to server. Do this:
this.uploadFileToUrl = function(file, title, text, uploadUrl){
var payload = new FormData();
payload.append("title", title);
payload.append('text', text);
payload.append('file', file);
return $http({
url: uploadUrl,
method: 'POST',
data: payload,
//assign content-type as undefined, the browser
//will assign the correct boundary for us
headers: { 'Content-Type': undefined},
//prevents serializing payload. don't do it.
transformRequest: angular.identity
});
}
Then use it:
MyService.uploadFileToUrl(file, title, text, uploadUrl).then(successCallback).catch(errorCallback);
Here is the complete solution
html code,
create the text anf file upload fields as shown below
<div class="form-group">
<div>
<label for="usr">User Name:</label>
<input type="text" id="usr" ng-model="model.username">
</div>
<div>
<label for="pwd">Password:</label>
<input type="password" id="pwd" ng-model="model.password">
</div><hr>
<div>
<div class="col-lg-6">
<input type="file" file-model="model.somefile"/>
</div>
</div>
<div>
<label for="dob">Dob:</label>
<input type="date" id="dob" ng-model="model.dob">
</div>
<div>
<label for="email">Email:</label>
<input type="email"id="email" ng-model="model.email">
</div>
<button type="submit" ng-click="saveData(model)" >Submit</button>
directive code
create a filemodel directive to parse file
.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 code
append the file and fields to form data and do $http.post as shown below
remember to keep 'Content-Type': undefined
.service('fileUploadService', ['$http', function ($http) {
this.uploadFileToUrl = function(file, username, password, dob, email, uploadUrl){
var myFormData = new FormData();
myFormData.append('file', file);
myFormData.append('username', username);
myFormData.append('password', password);
myFormData.append('dob', dob);
myFormData.append('email', email);
$http.post(uploadUrl, myFormData, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
.success(function(){
})
.error(function(){
});
}
}]);
In controller
Now in controller call the service by sending required data to be appended in parameters,
$scope.saveData = function(model){
var file = model.myFile;
var uploadUrl = "/api/createUsers";
fileUpload.uploadFileToUrl(file, model.username, model.password, model.dob, model.email, uploadUrl);
};
You're sending JSON-formatted data to a server which isn't expecting that format. You already provided the format that the server needs, so you'll need to format it yourself which is pretty simple.
var data = '"title='+title+'" "text='+text+'" "file='+file+'"';
$http.post(uploadUrl, data)
This never gonna work, you can't stringify your FormData object.
You should do this:
this.uploadFileToUrl = function(file, title, text, uploadUrl){
var fd = new FormData();
fd.append('title', title);
fd.append('text', text);
fd.append('file', file);
$http.post(uploadUrl, obj, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
.success(function(){
blockUI.stop();
})
.error(function(error){
toaster.pop('error', 'Errore', error);
});
}
Using $resource in AngularJS you can do:
task.service.js
$ngTask.factory("$taskService", [
"$resource",
function ($resource) {
var taskModelUrl = 'api/task/';
return {
rest: {
taskUpload: $resource(taskModelUrl, {
id: '#id'
}, {
save: {
method: "POST",
isArray: false,
headers: {"Content-Type": undefined},
transformRequest: angular.identity
}
})
}
};
}
]);
And then use it in a module:
task.module.js
$ngModelTask.controller("taskController", [
"$scope",
"$taskService",
function (
$scope,
$taskService,
) {
$scope.saveTask = function (name, file) {
var newTask,
payload = new FormData();
payload.append("name", name);
payload.append("file", file);
newTask = $taskService.rest.taskUpload.save(payload);
// check if exists
}
}
Assume that we want to get a list of certain images from a PHP server using the POST method.
You have to provide two parameters in the form for the POST method. Here is how you are going to do.
app.controller('gallery-item', function ($scope, $http) {
var url = 'service.php';
var data = new FormData();
data.append("function", 'getImageList');
data.append('dir', 'all');
$http.post(url, data, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
}).then(function (response) {
// This function handles success
console.log('angular:', response);
}, function (response) {
// this function handles error
});
});
I have tested it on my system and it works.
Angularjs
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]);
});
});
}
};
}]);
app.service('fileUpload', ['$http', function ($http) {
this.uploadFileAndFieldsToUrl = function(file, fields, uploadUrl){
var fd = new FormData();
fd.append('file', file);
console.log(file) //File { name: "franklindroosevelt1.jpg", lastModified: 1522139208000, lastModifiedDate: Date 2018-03-27T08:26:48.000Z, webkitRelativePath: "", size: 63159, type: "image/jpeg" }
for(var i = 0; i < fields.length; i++){
fd.append(fields[i].name, fields[i].data)
}
console.log(file)//File { name: "franklindroosevelt1.jpg", lastModified: 1522139208000, lastModifiedDate: Date 2018-03-27T08:26:48.000Z, webkitRelativePath: "", size: 63159, type: "image/jpeg" }
$http.post(Appname+"/upload_image/", fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
.success(function(){
})
.error(function(){
});
}
}]);
app.controller('myCtrl', ['$scope', 'fileUpload', function($scope, fileUpload){
$scope.$watch('myFile', function(newFileObj){
if(newFileObj)
$scope.filename = newFileObj.name;
});
$scope.uploadForm = function(){
var file = $scope.myFile;
var uploadUrl = "/formUpload";
var fields = [{"name": "filename", "data": $scope.filename}];
fileUpload.uploadFileAndFieldsToUrl(file, fields, uploadUrl);
};
}]);
HTML
<div class="maincontent">
<div ng-app="Appschedule" ng-controller="myCtrl" class="container container1">
<p>
<input type="file" file-model="myFile"/>
</p>
<p>
<label>File Name:</label>
<input type="text" ng-model="filename"></input>
</p>
<button ng-click="uploadForm()">upload me</button>
</div>
</div>
I had written a code to upload a image into directory , here i want to change the image name based on input text or any random name.I cant change the name , the name remains same while uploading. Is there any other way to send the name. please help me
Is there any other way to send the name?
Here is code showing how to send name as string and file in the same request:
myApp.service('fileUpload', ['$http', function ($http) {
this.uploadFileToUrl = function(file, uploadUrl){
var fd = new FormData();
fd.append('file', file);
var info = {
"text":"file_name"
};
fd.append('data', angular.toJson(info));
$http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
.success(function(){
})
.error(function(){
});
}
}]);
On server side it's in req.body.data, so it can be received i.e. like this:
upload(req, res, function (err) {
if (err) {
res.json({error_code: 1, err_desc: err});
return;
}
console.log(req.body.data);
res.json({error_code: 0, err_desc: null});
})
I am tryout on save in local project folder using angular and i have not correct code anyone put it your solution help me lot more and then my code here as
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(){
});
}
This is an example code to upload files. You can try it out using this example.
<html>
<head>
<script src = "https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
</head>
<body ng-app = "myApp">
<div ng-controller = "myCtrl">
<input type = "file" file-model = "myFile"/>
<button ng-click = "uploadFile()">upload me</button>
</div>
<script>
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', ['$https:', function ($https:) {
this.uploadFileToUrl = function(file, uploadUrl){
var fd = new FormData();
fd.append('file', file);
$https:.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);
};
}]);
</script>
Hey Kalithas KN and welcome to StackOverflow.
For file upload, I have found the following Angular JS library works the best for me
https://github.com/danialfarid/ng-file-upload
The upload method will look something like this
$scope.upload = function (file) {
Upload.upload({
url: 'upload/url',
data: {file: file, 'username': $scope.username}
}).then(function (resp) {
console.log('Success ' + resp.config.data.file.name + 'uploaded. Response: ' + resp.data);
}, function (resp) {
console.log('Error status: ' + resp.status);
}, function (evt) {
var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
console.log('progress: ' + progressPercentage + '% ' + evt.config.data.file.name);
});
};
In your template, you would do something like this
<div class="button" ngf-select="upload($file)">Upload on file select</div>
Also, the library can handle drag and drop file upload which i think is always a nice addition.
I hope this helps. Please let me know if you need more clarifications.
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;
}
};
I made this example: http://jsfiddle.net/ejx68/6/ to upload multi-part file but there are two things i can't do.
1) Upload more than one file. So use the multiple condition on input
2) append other formData() that i have in the controller to the service.
Here the example:
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, callback){
var fd = new FormData();
fd.append('file', file);
$http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
.success(callback)
.error(callback);
}
}]);
myApp.controller('myCtrl', ['$scope', 'fileUpload', function($scope, fileUpload){
$scope.uploadFile = function(){
var file = $scope.myFile;
console.log('file is ' + JSON.stringify(file));
console.log(fileUpload.fd);
fileUpload.fd.append('newID', "2");
var uploadUrl = "http://httpbin.org/post";
fileUpload.uploadFileToUrl(file, uploadUrl,function(data, status, headers, config){
if(status == 200)console.log('Success!');
else console.log('Error!');
});
};
}]);
<div ng-controller = "myCtrl">
<input type="file" file-model="myFile"/>
<button ng-click="uploadFile()">upload me</button>
</div>
thanks