blob file edit and upload in angularjs - angularjs

I am fetching a list of files (which may be of any type) from mysql database and converting them to byte[] and returning all the files of a particular user as an array of files in spring boot.
Now I need to display all the files in the front end and provide an option to edit the file so that the user can remove the already existing file with the new file.
So Whenever a particular file is edited I have to upload the file from front end using angular js.
The Problem is I am getting the files as an array in response.data. I am facing a problem here like, How to edit the a particular file in that array and send the list of files to the backend to store them.I tried to traverse through array of files and store each file as a blob object, but I am not sure of what is the content type of each file as it can be any type of file(.bmp,.pdf,.docx,.tif etc).
Also I am not sure if it is the rightway to do for editing the files, because it may alter the content of the existing file or may change the type of the exixsting file.
So Please suggest me a way to get the file from the database and edit the file if necessary and then push it back to the database.
My controller and services below:-
angular.module("app").service("serviceCalls", function($q, $rootScope, $http) {
this.landOwnerEditProfile = function(email){
var differed = $q.defer();
$rootScope.config.headers.Authorization = sessionStorage.Authorization;
$http
.get($rootScope.URL + "/landownerDetails/"+email+"/", $rootScope.config,{
responseType: 'blob'
})
.then(function(response) {
console.log("coupon service success");
differed.resolve(response);
})
.catch(function(response) {
differed.reject(response);
});
return differed.promise;
};
this.updateLandOwnerProfile = function(details, email) {
var differed = $q.defer();
$rootScope.config.headers.Authorization = sessionStorage.Authorization;
var formdata = new FormData();
// console.log($("#file"));
formdata.append("email", email);
formdata.append("fname", details.user.fname);
formdata.append("lname", details.user.lname);
formdata.append("city", details.user.city);
formdata.append("phone1", details.user.phone1);
formdata.append("phone2", details.user.phone2);
formdata.append("phone3", details.user.phone3);
formdata.append("streetAddressLine1", details.user.streetAddressLine1);
formdata.append("streetAddressLine2", details.user.streetAddressLine2);
formdata.append("stripeApiKey", details.user.stripeApiKey);
formdata.append("zipcode", details.user.zipcode);
formdata.append("businessName", details.user.businessName);
formdata.append("landOwnerEditProfile", true);
// var input_files = document.getElementsByClassName("files");
// for (var i = 0; i < input_files.length; i++) {
// console.log(input_files[i].files);
// for (var file of input_files[i].files) formdata.append("file", file.name);
// }
// formdata.append("file", input_files);
// for (var key of formdata.entries()) {
// console.log(key[0] + ", " + key[1]);
// }
for (var i = 0; i < details.files.length; i++) {
formdata.append("file", details.files[i].file);
}
$http
// .post("http://localhost:8090/", formdata, {
.post($rootScope.URL + "/user/landownerDetails/editProfile/"+email+"/", formdata, $rootScope.config,{
transformRequest: angular.identity,
headers: {
"Content-Type": undefined,
// "Authorization":$rootScope.config.headers.Authorization
}
})
.then(function(response) {
// console.log(response);
if(response.data.status!=true){
throw new Error(" Details Not Updated ");
}
console.log("Details updated success");
differed.resolve(response);
})
.catch(function(response) {
console.log("rejected", response);
differed.reject(response);
});
return differed.promise;
}})
angular
.module("app")
.controller("landOwnerEditProfile", function($state, $scope, $location, serviceCalls, $filter, $stateParams,$timeout) {
$scope.files = [];
serviceCalls.landOwnerEditProfile(sessionStorage.emailId)
.then((response)=>{
console.log(response.data);
let status = response.status;
if(status===200){
let landownerDetails = response.data;
let landowner = landownerDetails.dayleasingusers;
let userdocuments = landownerDetails.userdocuments;// userdocument is an array containing the files
$scope.user = {};
$scope.property={};
$scope.user.fname = landowner.fname;
$scope.user.lname = landowner.lname;
$scope.user.streetAddressLine1 = landowner.address1;
// $scope.user.streetAddressLine2 = landowner.address2 ||'sdasd';
$scope.property.propertyType = landowner.state || 'Alabama';
$scope.user.city = landowner.city;
$scope.user.zipcode = parseInt(landowner.zipCode);
$scope.user.phone1 = !!landowner.phone?parseInt(landowner.phone.substring(0,3)):null;
$scope.user.phone2 = !!landowner.phone?parseInt(landowner.phone.substring(3,6)):null;
$scope.user.phone3 = !!landowner.phone?parseInt(landowner.phone.substring(6)):null;
$scope.user.stripeApiKey = landowner.stripeApiKey;
$scope.user.businessName = landowner.businessName;
$scope.files = [];
for(let doc of userdocuments){
let blob = new Uint8Array(doc.filedata);
$scope.files.push({file:new Blob([blob],{ type:'contentType'})}); //I am not sure of the contentType here.
// $scope.files.push({file:new Blob([doc.filedata],{ type:'multipart/form-data'},doc.filename)});
// $scope.files.push({file:new File([doc.filedata],doc.filename)});
}
}
else{
throw new Error(response.statusText);
}
})
.catch((error)=>{
console.log(error);
})
serviceCalls.updateLandOwnerProfile($scope, sessionStorage.emailId)
.then(function(response) {
console.log(response);
})
.catch(function(error) {
})

Related

Pass array of data in angularjs multipart

I have an array of colors and sizes, and some other data like product_name and images, I am able to send image files and product_name but when I attach color_and_sizes array then it says 500 error
Here is my Code :(Angularjs and Laravel Controller )
Basically I want to save all the details in the database but I am unable to save the color and sizez details.
$scope.admin_add_product=function(){
var product_name=$scope.txtProductname;
var product_description=$scope.tarDescription;
var price=$scope.txtprice;
var unit_in_stock=$scope.txtunitinstock;
var unit_weight=$scope.txtweight;
var file = $scope.front_image;
var file2=$scope.back_image;
var file3=$scope.left_side_image;
var file4=$scope.right_side_image;
var main_image=$scope.main_image;
var large_image=$scope.large_image;
var category_id=$scope.selectedCategory.category_id;
var sub_category_id=$scope.selectedSubCategory.sub_category_id;
var sub_sub_category_id=$scope.selectedSubSubCategory.sub_sub_category_id;
var product_key=$scope.addProductOption;
var tags=$scope.txt_tags;
var aditional_information=$scope.txt_aditional_information;
var temp_color_and_size=[];
temp_color_and_size=$scope.color_and_size;
console.log(temp_color_and_size);
var uploadUrl = 'http://web.com/app/add_product';
fileUpload.uploadFileToUrl(file,file2,file3,file4,main_image,large_image, product_name,product_description,price,category_id,sub_category_id,sub_sub_category_id,unit_in_stock,unit_weight,product_key,tags,aditional_information ,temp_color_and_size, uploadUrl);
}
/* ---------------------------------------------------- Color and Sizes -------------------------------------------------- */
$scope.color_and_size=[];
$scope.Add=function(){
var c_and_s=[];
c_and_s.color_name = document.getElementById('cl1').value;
var s;
if($scope.sizes!=null)
{
for(var i=0;i<$scope.sizes.length-1;i++)
{
if($scope.sizes[i+1]>=0 && $scope.sizes[i+1]<=9)
{
}
else
{
if($scope.sizes[i+2]>=0 && $scope.sizes[i+2]<=9)
{
}
else
{
$scope.sizes = $scope.sizes.substring(0, i+1);
}
}
}
console.log($scope.sizes);
$scope.size=$scope.sizes.split(',');
c_and_s.sizes=$scope.size;
}
$scope.color_and_size.splice(0,0,c_and_s);
console.log($scope.color_and_size);
document.getElementById('cl1').value="#000000";
$scope.sizes="";
}
myApp.service('fileUpload', ['$http', function ($http) {
this.uploadFileToUrl = function(file,file2,file3,file4,main_image,large_image,product_name,product_description,price,category_id,sub_category_id,sub_sub_category_id,unit_in_stock,unit_weight,product_key,tags,aditional_information,temp_color_and_size, uploadUrl){
console.log(product_name);
console.log(product_description);
console.log(price);
console.log(unit_in_stock);
console.log(unit_weight);
console.log(file);
console.log(temp_color_and_size);
console.log(product_key);
console.log(tags);
console.log(aditional_information);
var payload = new FormData();
payload.append("product_name", product_name);
payload.append('product_description', product_description);
payload.append('price', price);
payload.append('unit_in_stock', unit_in_stock);
payload.append('unit_weight', unit_weight);
payload.append('file', file);
payload.append('file2', file2);
payload.append('file3', file3);
payload.append('file4', file4);
payload.append('main_image', main_image);
payload.append('large_image', large_image);
payload.append('product_key', product_key);
payload.append('tags', tags);
payload.append('aditional_information', aditional_information);
payload.append('temp_color_and_size', temp_color_and_size);
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(function (response){
alert('Product Added Successfully');
window.location = "http://web.com/add_product"
},function (error){
});
}
}]);
Please help me to resolve this problem.
Your question is not clear to me but I think the problem is that all properties of the formData object apart from temp_color_and_size are string type and temp_color_and_size is a javascript object. This might solve your problem.
payload.append('temp_color_and_size', JSON.stringify(temp_color_and_size);
You have to deserialize JSON string on the server side.

How to pass $scope variable data into node.js backend server file?

I have json data in $scope variable and i want to use that $scope variable inside my backend app.js node file.
This is my backend file app.js:
app.post('/upload', upload.single('file'), function(req, res) {
var XLSX = require('xlsx');
var workbook = XLSX.readFile('./uploads/' + req.file.filename);
var sheet_name_list = workbook.SheetNames;
var data = XLSX.utils.sheet_to_json(workbook.Sheets[sheet_name_list[0]]);
//var values = [];
console.log(data);
return res.status(200).send(data);
});
app.post('/api/uploadlast',api.addNewContact, function(req,res){
Contact.bulkCreate(excels).then(function(users) {
return res.status(200).send(users);
}).catch(Sequelize.ValidationError, function(err) {
return res.status(422).send(err.errors[0].message);
}).catch(function(err) {
return res.status(400).send(err.message);
});
})
This is my controller file:
$scope.uploadFile = function() {
var file = $scope.myFile;
var uploadUrl = "/upload";
var fd = new FormData();
fd.append('file', file);
$http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers: {
'Content-Type': undefined
}
})
.then(function(response) {
//$state.reload();
$scope.excels = response.data;
console.log("success!!");
})
.catch(function() {
console.log("error!!");
});
}
$scope.uploadLast = function() {
$http.post('/api/uploadlast').then(function(response) {
$state.reload();
});
}
})
I want to get $scope.excels data into my backend to bulkcreate into databases.
You can pass any data with a post request as the second parameter of $http.post(). So you can do something like:
$scope.uploadLast = function() {
var data = {
excels: $scope.excels
};
$http.post('/api/uploadlast', data).then(function(response) {
$state.reload();
});
}
And in your backend, you can access it like:
app.post('/api/uploadlast',api.addNewContact, function(req, res){
var data = req.body.excels;
Contact.bulkCreate(data).then(function(users) {
return res.status(200).send(users);
}).catch(Sequelize.ValidationError, function(err) {
return res.status(422).send(err.errors[0].message);
}).catch(function(err) {
return res.status(400).send(err.message);
});
});

Angular FIle upload Custom headers for upload all

I want to add custom headers to a file before Uploading. Both methods below are not working:
$scope.uploadallman = function (qID) {
alert(qID);
uploader.headers = { QuestionID: qID };
//item.headers = {
// MyHeader: qID,
//};
uploader.uploadAll();
}
Maybe not the best solution, but it's the way I do it and it's working.
function _uploadFile(resourceURL, file) {
var deferred = $q.defer();
var config = {};
config.headers = {};
config.transformRequest = angular.identity;
config.headers['Content-Type'] = undefined;
// config.headers['MyCustomHeaderKey'] = MyCustomHeaderValue; // Optional
var formData = new FormData();
formData.append('file', file);
// formData.append('myCustomFormDataAttributeKey', myCustomFormDataAttributeValue); // Optional
$http.post(resourceURL, formData, config)
.success(function (response) {
deferred.resolve(response);
})
.error(function (err, status) {
deferred.reject(err);
});
return deferred.promise;
}
This is very good topic about the file upload in Angular:
How to POST JSON and a file to web service with Angular?

how to convert image file in byte array angular?

I am struggling converting image to byte array using client side script. I have to convert image to byte array, and pass this array to web service , so that the web services can save the image in server. Any one please help me.
$scope.file=function(user){
//console.log("hhhhh",angular.toJson($scope.user));
console.log(ContextService.object);
$scope.users=ContextService.object;
console.log($scope.user);
//$scope.file=$scope.file;
console.log($scope.user.file);
var file=$scope.user.file;
var bytes = [];
var fileReader = new FileReader();
fileReader.onload = function (e) {
var naveen=fileReader.result;
for (var i = 0; i < naveen.length; ++i)
{
bytes.push(naveen.charCodeAt(i));
bytes.push(0);
}
console.log("bytes",bytes);
$scope.call(bytes);
};
fileReader.onerror = function(err) {
console.log(err);
};
fileReader.readAsBinaryString(file);
$scope.call=function(bytes)
{
$scope.image=bytes;
}
$timeout(function() {
console.log("vvvvv",$scope.image);
$scope.users.file=$scope.image;
console.log("dsfdsfds",$scope.users);
var url = "http://127.0.0.1:8080/api/signup";
$http({
method : "POST",
url : url,
data :angular.toJson($scope.users),
headers : {
"content-type" : "application/json",
"Accept" : "application/json"
}
})
.success(function(data) {
console.log("Detail", angular.toJson(data));
$state.go("login");
});
}, 3000);

How to render errors to client? AngularJS/WebApi ModelState

I'm building an AngularJS SPA application with WebApi for the backend. I am using attributes for model validation on the server, if validation fails this is what I return from the ModelState.
{"Message":"The request is invalid.","ModelState":{"model.LastName":["Last Name must be at least 2 characters long."]}}
How do I then render this to the client with AngularJS?
//Save User Info
$scope.processDriverForm = function(isValid) {
if (isValid) {
//set button disabled, icon, text
$scope.locked = true;
$scope.icon = 'fa fa-spinner fa-spin';
$scope.buttonText = 'Saving...';
$scope.submitted = true;
$scope.formData.birthDate = $scope.formData.birthMonth + '/' + $scope.formData.birthDay + '/' + $scope.formData.birthYear;
$http({
method: 'POST',
url: 'api/Account/Register',
data: $.param($scope.formData),
headers: { 'Content-Type': 'application/x-www-form-urlencoded' } // set the headers so angular passing info as form data (not request payload)
})
.success(function (data) {
console.log(data);
toastr.success('User ' + $scope.formData.username + ' created!');
$scope.userForm.$setPristine();
$scope.formData = {};
//reset the button
$scope.locked = false;
$scope.icon = '';
$scope.buttonText = 'Save';
//reset validation submitted
$scope.submitted = false;
})
.error(function (data, response) {
console.log(data);
toastr.error('Ooops! There was an error creating the user. Try again and if the problem persists, contact Support.');
//reset the button
$scope.locked = false;
$scope.icon = '';
$scope.buttonText = 'Save';
$scope.submitted = false;
var resp = {};
var errors = [];
for (var key in resp.ModelState) {
for (var i = 0; i < resp.ModelState[key].length; i++) {
errors.push(resp.ModelState[key][i]);
}
}
$scope.errors = errors;
});
}
else {
toastr.warning('Invalid User Form, correct errors and try again.');
}
};
When making your call to your server, capture the error based upon the rejection of the $http promise.
Then in your controller I would suggest flattening the response to an array of errors upon handling of the error for display as shown in this fiddle example:
for (var key in resp.ModelState) {
for (var i = 0; i < resp.ModelState[key].length; i++) {
errors.push(resp.ModelState[key][i]);
}
}
To put it all together:
// Post the data to the web api/service
$http.post(url, data)
.success(successHandler)
.error(function (response) {
// when there's an error, parse the error
// and set it to the scope (for binding)
$scope.errors = parseErrors(response);
});
//separate method for parsing errors into a single flat array
function parseErrors(response) {
var errors = [];
for (var key in response.ModelState) {
for (var i = 0; i < response.ModelState[key].length; i++) {
errors.push(response.ModelState[key][i]);
}
}
return errors;
}
The simplest way might be to grab all the errors from ModelState and put them into a new property on $scope.
$http.post(url, data).
success(successHandler).
error(function (response) {
$scope.errors = getErrors(response);
});
function getErrors(responseWithModelState) {
var errors = [];
/*
Get error messages out of ModelState property, and push them into the errors variable...
Brocco beat me to it. :-)
*/
return errors;
};
Then in your HTML...
<ul>
<li ng-repeat="e in errors">{{e}}</li>
</ul>
Or, instead of doing this in every error handler, you could write it once and have it apply to every HTTP request by using an interceptor. I've never written one myself, so I'll just point you to the doc (scroll down to the Interceptors section).

Resources