need help uploading images - angularjs

I'm trying to upload an object file which contains 2 attributes, a name and a picture using AngularJS. I know that this topic has been treated multiple times but no matter what I read I can't seem to make it work.
I'm using Java Spring for my server and when I try to upload a "Character" (name + picture) through my client I get this error in my server : "Required request body content is missing"...
Here is my code :
.config(function($stateProvider, $httpProvider, $resourceProvider) {
$resourceProvider.defaults.stripTrailingSlashes = false;
$httpProvider.defaults.transformRequest = function(data) {
if (data === undefined)
return data;
var fd = new FormData();
angular.forEach(data, function(value, key) {
if (value instanceof FileList) {
if (value.length == 1) {
fd.append(key, value[0]);
} else {
angular.forEach(value, function(file, index) {
fd.append(key + '_' + index, file);
});
}
} else {
fd.append(key, value);
}
});
return fd;
}
$httpProvider.defaults.headers.post['Content-Type'] = undefined;
And here is my service :
angular.module('myApp.services', ['ngResource'])
.factory('Character', function($resource) {
return $resource('http://localhost:8080/myApp/character/:id',
{ id: '#id' },
{ update: { method: 'GET', transformRequest: angular.identity, headers: { 'Content-Type': undefined } } }
);
})
.service('popupService', function($window){
this.showPopup = function(message){
return $window.confirm(message);
}
});
And finally this is how I'm using it in my controller :
.controller('CharacterCreateController',function($scope,$state,$stateParams,Character){
$scope.character = new Character();
$scope.addCharacter = function(){
$scope.character.$save(function(){
$state.go('characters');
});
}
})
Could anyone please help me ??? I really don't know what to do and it's my first time trying to upload files using Angular.

Related

Angularjs Form data is not binding at server side during file uploade

When im tring to uploade my file into server im getting an Error as TypeError: $http(...).success is not a function(…)
Angular File change code
$scope.ChechFileValid = function (file) {
debugger;
var isValid = false;
if ($scope.SelectedFileForUpload != null) {
if ((file.type == 'image/png' || file.type == 'image/jpeg' || file.type == 'image/gif') && file.size <= (512 * 1024)) {
$scope.FileInvalidMessage = "";
isValid = true;
}
else {
$scope.FileInvalidMessage = "Selected file is Invalid. (only file type png, jpeg and gif and 512 kb size allowed)";
}
}
else {
$scope.FileInvalidMessage = "Image required!";
}
$scope.IsFileValid = isValid;
};
This is my file submit button Code
$scope.SaveFile = function () {
$scope.IsFormSubmitted = true;
$scope.Message = "";
$scope.ChechFileValid($scope.SelectedFileForUpload);
if ($scope.IsFormValid && $scope.IsFileValid) {
FileUploadService.UploadFile($scope.SelectedFileForUpload, $scope.FileDescription).then(function (d) {
alert(d.Message);
ClearForm();
}, function (e) {
alert(e);
});
}
else {
$scope.Message = "All the fields are required.";
}
};
This is my factory code
fac.UploadFile = function (file, description) {
var formData = new FormData();
formData.append("file", file);
formData.append("description", description);
var defer = $q.defer();
return $http({
url: 'http://localhost:59838/Api/Home/Sales',
data: JSON.stringify(formData),
headers: { 'content-type': 'application/json' },
transformRequest: angular.identity,
method: 'POST',
})
.success(function (d) {
defer.resolve(d);
})
Here im getting Error as angular.js:15018 Possibly unhandled rejection: {"data":{"Message":"No HTTP resource was found that matches the request URI 'http://localhost:59838/Api/Home/Sales'.","Message
You are getting the $http(...).success is not a function(…)
because the ".success" method has since been deprecated, use ".then" instead. More info on the following link Check Deprecation notice
As for the second error, it could be the result of improper URI, maybe your route is expecting a query parameter, ie : http://localhost:59838/Api/Home/Sales?XXXX, check the full error for more infos
ie : (No HTTP resource was found that matches the request URI ..."
(parameter XXXX is mandatory))

Angularjs 1.7.x, How can I caught success after method executed, provided the method is executed from other file nd has its own success handler?

$scope.uploadAppFile = function(element) {
console.log("uploadAppFile : selectedAppId "+$scope.selectedAppId);
$rootScope.uploadFile(element.files, $scope.selectedAppId, element.id, $scope,false);
}
Above is my uploadAppFile code from upload.js file, I am invoking rootScope js file API.
$rootScope.uploadFile = function(files, applicationId, documentId, scope, isUserDoc) {
if ($rootScope.isEmpty(documentId)) {
Notification.warning("Document id is null or empty !!");
return;
}
var formData = new FormData();
formData.append("file", files[0]);
var data = {};
data.applicationId = applicationId;
data.documentId = documentId;
if(isUserDoc != undefined && isUserDoc != null){
data.isUserDocument = isUserDoc;
}
formData.append("uploadRequest", JSON.stringify(data));
$http({
method : "POST",
enctype : 'multipart/form-data',
url : URLS.user + "/upload",
headers : {
'Content-Type' : undefined,
'token' : $cookieStore.get(Constant.TOKEN)
},
data : formData,
processData : false,
cache : false
})
.then(
function success(response) {
if (response.data.status == 200) {
if (response.data.data.isFileUpload) {
Notification.info("Successfully Uploaded !!");
} else {
Notification.warning("File can't uploaded !!");
}
} else if (response.data.status == 400) {
Notification.warning(response.data.message);
}
}, function errorCallback(error) {
$rootScope.validateErrorResponse(error);
});
}
Above is my rootScope.js file where upload file method is declared.
I wanted to make call from my upload.js file as below, external success caught
$rootScope.uploadFile(element.files, $scope.selectedAppId, element.id, $scope,false).then(function(success){//Do stuff here});
Is this possible, because I want to check once file uploded then enable few options on UI, I dont want modify rootScope.js as it is common and generic one.
Define a service or a factory instead. Docs: https://docs.angularjs.org/guide/services
Return a promise on success/fail using
return $q.resolve()
or
return $q.reject();
and remember to add return on the http also. after that you can do a .then on the caller (uploadFiles).
I know you said not to modify rootScope.js however there is no other way to be notified of an async task completion, without you doing sending some kind of a message back and forth either via event or promise.
Anyway, if you really wanted to not change rootScope.js, you can just do some kind of nasty loop and wait for the notification with a message to show up :) (extremely Do Not recommend this, don't do it.)
Code below on what it should look like with promise. (remember to inject $q)
$rootScope.uploadFile = function(files, applicationId, documentId, scope, isUserDoc) {
if ($rootScope.isEmpty(documentId)) {
Notification.warning("Document id is null or empty !!");
return $q.reject();
}
var formData = new FormData();
formData.append("file", files[0]);
var data = {};
data.applicationId = applicationId;
data.documentId = documentId;
if(isUserDoc != undefined && isUserDoc != null){
data.isUserDocument = isUserDoc;
}
formData.append("uploadRequest", JSON.stringify(data));
return $http({
method : "POST",
enctype : 'multipart/form-data',
url : URLS.user + "/upload",
headers : {
'Content-Type' : undefined,
'token' : $cookieStore.get(Constant.TOKEN)
},
data : formData,
processData : false,
cache : false
})
.then(
function success(response) {
if (response.data.status == 200) {
if (response.data.data.isFileUpload) {
Notification.info("Successfully Uploaded !!");
return $q.resolve();
} else {
Notification.warning("File can't uploaded !!");
return $q.reject();
}
} else if (response.data.status == 400) {
Notification.warning(response.data.message);
return $q.reject();
}
}, function errorCallback(error) {
$rootScope.validateErrorResponse(error);
return $q.reject();
});
}
$scope.uploadAppFile = function(element) {
console.log("uploadAppFile : selectedAppId "+$scope.selectedAppId);
$rootScope.uploadFile(element.files, $scope.selectedAppId, element.id, $scope,false)
.then(function(){
//success
}, function(){
//failed
});
}
This wont break any existing usage of the rootScope.js files. There are more optimizations to be made however, this should answer your question

Image uploading from angularjs 1.5 to grails 3 as byte[] and save it in postgresql as bytea

I have searched for a solution in several days now. There are many examples where people is trying to upload a picture.
I really need some help to come trough this. I have some code here and I hope someone could push me to through this.
I have added my code in this link
//Angularjs controller :
self.createVaerksted = function(id, navn, by, nummer, billede) {
var data = {};
data.vaerkstedNavn = navn;
data.byNavn = by;
data.vaerkstedNummer = nummer;
data.myImage = billede[0];
vaerkstedService.createVaerksted(data)
.then(function(response) {
console.log(response)
})
// Angularjs service
var prefix = 'http://localhost:8080/api/';
createVaerksted: function(data) {
return $http.post(prefix + 'saveVaerksted', data)
}
Thank you in advance
To upload a file (image, xls, etc) with AngularJS you can use a FormData.
For example, using Angular profile you can create a angular controller:
function UploadExcelController(domainServiceFactory, contextPath, $log, $state, $stateParams) {
var vm = this;
vm.contextPath = contextPath;
var UploadExcel = domainServiceFactory('/api/uploadExcel/:id', {id: '#id'}, {
create: {
method: "POST",
transformRequest: angular.identity,
headers: { 'Content-Type': undefined }
}
});
vm.uploadExcel = function(data){
var fd = new FormData();
fd.append("year", data["year"]);
fd.append("excelFile", data["excelFile"][0]);
$log.info(fd)
UploadExcel.create({}, fd).$promise.then(function (res) {
$state.go('dashboard');
}).catch(function (err) {
$log.info("error "+err);
alert(""+err);
throw err;
});
}
Create a Grails Command:
class UploadExcelCommand implements Validateable {
MultipartFile excelFile
Integer year
static constraints = {
year nullable: false
excelFile validator: { val, obj ->
if ( val == null ) {
return false
}
if ( val.empty ) {
return false
}
['xlsx'].any { extension ->
val.originalFilename?.toLowerCase()?.endsWith(extension)
}
}
}
and do the bussiness logic in the controller:
class UploadExcelController {
static responseFormats = ['json', 'xml']
def save(UploadExcelCommand cmd) {
if( cmd.hasErrors() ) {
render 404
return
}
if( Excel.get(cmd.year) ){
render 404
return
}
println cmd.year
println cmd.excelFile.inputStream
render "OK"
}
}

$cordovaFileTransfer can not work

use $cordovaFileTransfer to upload images,but it stop at 99%, $_FILES is empty in PHP;
and i get evt object.
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"16656","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"33040","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"98576","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"131344","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"147728","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"164112","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"180496","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"213264","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"229648","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"65808","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"82192","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"114960","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"295184","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"262416","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"311568","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"327952","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"344336","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"360720","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"377104","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"409872","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"442640","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"393488","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"426256","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"459024","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"475408","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"491163","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"196880","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"246032","total":"491176"}
what's wrong with the property loaded;why it increase repeatly;
upload code
$scope.upload = function(imageURI) {
$scope.dangerList[$scope.setting.num][$scope.setting.imageType + '1pic'] = imageURI;
var server = 'http://localhost/test.php';
var dirName = 'check';
var desName = 'test';
var options = {
'httpMethod': 'POST',
'params': {
'dirName': dirName,
'desName': desName
}
};
var promise = $cordovaFileTransfer.upload(server, imageURI, options, true);
promise.then(function(data) {
console.log(data);
}, function(data) {}, function(evt) {
$ionicLoading.show({
template: '<p>upload:' + parseInt(100.0 * evt.loaded / evt.total) + '%</p>',
//duration: 1000,
});
});
return promise;
};
and ngCordova\src\plugins\fileTransfer.js
angular.module('ngCordova.plugins.fileTransfer', [])
.factory('$cordovaFileTransfer', ['$q', '$timeout', function($q, $timeout) {
return {
download: function(source, filePath, options, trustAllHosts) {
var q = $q.defer();
var ft = new FileTransfer();
var uri = (options && options.encodeURI === false) ? source : encodeURI(source);
if (options && options.timeout !== undefined && options.timeout !== null) {
$timeout(function() {
ft.abort();
}, options.timeout);
options.timeout = null;
}
ft.onprogress = function(progress) {
q.notify(progress);
};
q.promise.abort = function() {
ft.abort();
};
ft.download(uri, filePath, q.resolve, q.reject, trustAllHosts, options);
return q.promise;
},
upload: function(server, filePath, options, trustAllHosts) {
var q = $q.defer();
var ft = new FileTransfer();
var uri = (options && options.encodeURI === false) ? server : encodeURI(server);
if (options && options.timeout !== undefined && options.timeout !== null) {
$timeout(function() {
ft.abort();
}, options.timeout);
options.timeout = null;
}
ft.onprogress = function(progress) {
q.notify(progress);
};
q.promise.abort = function() {
ft.abort();
};
ft.upload(filePath, uri, q.resolve, q.reject, options, trustAllHosts);
return q.promise;
}
};
}]);
and push interceptor
.factory('UserInterceptor', function ($q, $rootScope) {
return {
request:function(config){
config.headers = config.headers || {};
config.headers.UID = $rootScope.user.id || 0;
return config;
},
requestError: function(err){
return $q.reject(err);
},
response: function (response) {
return response;
},
};
})
it could work few days ago.
during the time,
add plaform with android#5.1.1 instead of android#4.1.1;
update cordova;
use ionic 1.7.3 now;
and here is the download code,it can works,but will download file twice
$scope.down = function(fname) {
var fileTransfer = new FileTransfer();
var uri = encodeURI($rootScope.rootUrl + fname);
var fileURL = cordova.file.externalRootDirectory + fname;
fileTransfer.download(
uri,
fileURL,
function(entry) {
console.log(entry);
},
function(error) {
console.log(error);
},
false, {
headers: {
"Authorization": "Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA=="
}
}
);
};
This is actually the response from progress event of cordovaFileTransfer.
On success it'll give response something like this:
Object {bytesSent: 3228135, responseCode: 200, response: "<!-- Served from 80.251.0.59 / test.talia.net, as …imited↵</p>↵↵</td></tr></table>↵↵</body>↵</html>↵", objectId: ""}
But as per the output you are getting,I think the function is getting interrupted by the same method from another instance because your whole file was almost uploaded in the 3rd last line.
"cancelable":"false","lengthComputable":"true","loaded":"491163","total":"491176"}
And then it picked up from some another point.
Please provide the code so I can try to assist you further.
Thank you

Using $resource to upload file

I have gone through all the questions on this website on this topic and pretty much tried all codes. Following is the latest snippet that I have borrowed from the answers listed on this website. I am trying to upload a file asynchronously to AWS s3 endpoint. I get my signed url correctly but am unable to actually upload the file.
HTML:
<form name="Details" ng-controller="DetailsController">
<input type="file" file-input="files" />
<button ng-click="initUpload()">Upload</button>
</form>
fileInput Directive and DetailsController:
module.directive('fileInput', ['$parse', function ($parse) {
return {
restrict: 'A',
link:function(scope, elm, attrs){
elm.bind('change', function(){
$parse(attrs.fileInput)
.assign(scope, elm[0].files);
scope.$apply();
});
}
}
}]).controller("DetailsController", ["$scope", "PostalService",
function ($scope, PostalService) {
getSignedURLForUpload = function(userId, filename, filetype){
return (PostalService.getSignedURLForUpload(userId, filename, filetype));
};
$scope.initUpload = function(){
var signedUrl = getSignedURLForUpload($scope.userId, $scope.files[0].name,$scope.files[0].type);
signedUrl.then(function (data) {
var uploadPromise = PostalService.uploadFile($scope.files, data.signedRequest);
uploadPromise.then(function(result) {
$scope.awsurl = data.url;
});
});
};
]);
PostalService:
module.factory("PostalService",
["$resource",
function($resource) {
var functions = {
getSignedURLForUpload: function(userId, filename, filetype) {
var SignUrl = $resource("host end point?userid="+userId+"&file-name="+filename+"&file-type="+filetype);
var promise = SignUrl.get().$promise;
return promise;
},
uploadFile: function(file, signedRequest) {
var Upload = $resource(signedRequest, null, {
'save':{
method: 'POST',
transformRequest: function(data){
var fd = new FormData();
angular.forEach(data, function(value, key) {
if(value instanceof FileList) {
if(value.length ===1){
fd.append(key, value[0]);
}else {
angular.forEach(value, function(file, index){
fd.append(key+'_'+index, file);
});
}
}else {
fd.append(key, value);
}
});
return fd;
},
headers: {'Content-Type' : undefined}
}
});
var promise = Upload.save(file).$promise;
return promise;
}
};
return functions;
}
]);
So the issue was in implementation of uploadFile function of PostalService.
The headers needed to be set properly:
1. 'Content-Type' : 'image/jpeg'
2. Authorization: 'undefined'
Authorization headers were being automatically set by my application and in this case, I had to nullify them as the particular url link used to upload the file to the server was pre-signed and signature was part of the query.
Content type needed to be 'image/jpeg' and not undefined as that was expected by my backend server.
Finally, the method 'POST' didn't work. Had to replace it with 'PUT' instead.

Resources