How to upload files with angularjs and laravel 5.2? - angularjs

I want to upload an image to the server with angularjs
var fileInputElement = $('input[name=avatar]');
var formData = new FormData();
formData.append("team_name", $('input[name=team_name]').val());
formData.append("associated_users", $('input[name=associated_users]').val()); // number 123456 is immediately converted to a string "123456"
// HTML file input, chosen by user
formData.append("avatar", fileInputElement[0].files);
$http.post('groups', formData)
.then(
function (response) {
console.log(response);
//$scope.teams.push(response.data)
},
function (response) {
console.log(response);
}
);
but in my controller when i return the avatar like this:
return "avatar =>" . Input::file('avatar');
the result is :
data:"avatar =>"
i don't know what's wrong with this code?

Related

send base64 string data to server but receive empty form value

I have a front-end written in Vue and a backend written in Golang. I'm using Google app engine to run my backend service, and use gcloud datastore and gcloud storage to store the data and image that were submitted through front-end form.
I've been trying to upload an image using POST method. I convert the image to a base64 string. Then I add the data string to formdata and POST to my backend service. I keep getting empty form value in Go program. Is there a reason that Go cannot read base64 string, or I miss something important about FormData? Any help helps, thank you.
My front-end code:
var myForm = document.getElementById('myForm')
var formData = new FormData(myForm)
var imgBase64 = getBase64(//image-url//)
imgBase64.then(function (res) {
formData.append('image', res)
}
axios.post(' //go-app-engine-service// ', formData)
.then(res => {
console.log(res)
})
.catch(error => {
console.log(error)
})
function getBase64(url) {
return axios
.get(url, {
responseType: 'arraybuffer'
})
.then(response => Buffer.from(response.data, 'binary').toString('base64'))}
My Go code:
imgString := r.FormValue("image")
fmt.Printf("imgstring: %s, %d, %T\n", imgString, len(imgString), imgString) //=> getting empty imgString
Ok, after some research I realize the "scope" issue.
function getBase64 returns a Promise and have to handle the value inside the scope, so I move the axios.post in the Promise and I finally see the base64 value in Go program. Problem solved.
modified front-end code:
var myForm = document.getElementById('myForm')
var formData = new FormData(myForm)
var imgBase64 = getBase64(//image-url//)
imgBase64.then(function (res) {
formData.append('image', res)
axios.post(' //go-app-engine-service// ', formData)
.then(res => {
console.log(res)
})
.catch(error => {
console.log(error)
})
}

PUT Request with AngularJS and Express

When I'm performing a put request and console.log(response) of the request I only get a JSON Object like {"res":1} instead of getting the whole json object with its changes in order to update him in a database.
Controller :
$scope.doneEdit = function (components) {
console.log(components);
components.editing = false;
if (components.editing === false) {
$http.put('/propt/' + components._id).then(function (response) {
console.log(response.data);
});
}
}
Express
app.put('/propt/:id', function(req,res) {
console.log(req.body);
testDb.update({_id:req.params.id}, req.body, {}, function(err, numReplaced){
res.statusCode = 200;
res.send(req.body);
})
})
You should pass the data you want to send as a second parameter to put method:
$http.put('/propt/' + components._id, {someValue:components.someValue})
You can find the documentation here: https://docs.angularjs.org/api/ng/service/$http#put

Spring MultipartException: The current request is not a multipart request

I'm trying to upload a file with AngularJS and Spring controller.
The Angular controller looks like this:
$scope.uploadFile=function(){
var formData=new FormData();
formData.append("file",file.files[0]);
$http.post('/content-files/upload /', file.files[0], {
transformRequest: function(data, headersGetterFunction) {
return data; // do nothing! FormData is very good!
},
headers: {'Content-Type': undefined }
})
.success(function(){
console.log('Post Succeded !');
})
.error(function(){
console.log('Post Failed .');
});
}
I also try this:
var formData = new FormData();
formData.append('file',file.files[0]);
$http.post('/content-files/upload /', formData, {
headers: { 'Content-Type': undefined },
transformRequest: angular.identity
})
and the Spring controller looks like this:
#RequestMapping(value = "/content-files/upload/", method = RequestMethod.POST )
public #ResponseBody String handleFileUpload( #RequestParam("file") MultipartFile file) {
System.out.println("BrandController.uploadMultipart()");
String name=file.getName();
if (!file.isEmpty()) {
try {
byte[] bytes = file.getBytes();
BufferedOutputStream stream =
new BufferedOutputStream(new FileOutputStream(new File(name)));
stream.write(bytes);
stream.close();
return "You successfully uploaded " + name + "!";
} catch (Exception e) {
return "You failed to upload " + name + " => " + e.getMessage();
}
} else {
return "You failed to upload " + name + " because the file was empty.";
}
}
My html Page is :
<form enctype="multipart/form-data">
<input id="file-0a" class="file" type="file" file-model="myFile" name="myFile" />
<button ng-click="uploadFile()">upload me</button></form>
i have 2 jars in web-inf/lib:commons-upload.jar and commons-io.jar
I add this in my spring configuration file:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="50000000"/>
</bean>
When I'm trying to upload a file, I get the error:
org.springframework.web.multipart.MultipartException: The current request is not a multipart request
When I'm trying to upload a file using MultipartHttpServletRequest in my spring function instead of Multipart i get this error:
java.lang.IllegalStateException: Current request is not of type [org.springframework.web.multipart.MultipartHttpServletRequest]: org.apache.catalina.connector.RequestFacade#196f5636
When i use HttpServletRequest request and i try to cast it i got a ClassCastException.
Nothing change when i cancel enctype="multipart/form-data" from my form Tag
Two things needed:
1. headers: {'Content-Type': 'application/x-www-form-urlencoded'}
2. The data passed should be converted to a URL-encoded string
reference:
enter link description here
I stuck into the same problem. Below is angular code
things you should do:
Remove the Content-Type from headers.
For multi file upload use below code
handleImageUpload = async (event) => {
if (event.target.files && event.target.files) {
const files = event.target.files;
_.map(files, (file) => {
//array for multiple files upload
this.imageData.push(file);
const reader = new FileReader();
//base64 encoded image for preview
reader.onload = async (event: any) => {
this.album.push(event.target.result);
};
reader.readAsDataURL(file);
});
this.uploadedImage = Promise.resolve(this.album);
}
}
In you submit handler use this code
const formData: any = new FormData();
// adding multiple files
this.imageData.map((i) => {
formData.append("files", i);
});
// add objects
_.map(body,(value,key) => {
formData.append(key, value);
});
// delete headers it will be set by browser
headers = headers.delete("Content-Type");
// make a call to api
this.httpClient
.post(url, formData, { headers })
.subscribe((res) => console.log(res));

AngularJS - how to read a image file's data?

I suppose to send the image data's to back-end. for that, i am try to read the file ( image ). But I turn up with a error as :
Uncaught TypeError: Failed to execute 'readAsArrayBuffer' on 'FileReader': parameter 1 is not of type 'Blob'.
how to fix it. or what is the correct way to read a image file?
here is my `directive'
var userPhotoUpload = function () {
return {
link : function (scope, element, attrs) {
var photoInput = element.find('.uploadField');
var r = new FileReader();
element.on('click', function () {
photoInput[0].click();
});
photoInput.on('change', function ( e ) {
var data = event.target.result;
r.readAsArrayBuffer(photoInput[0]);
// console.log( "data", data, e.target.result );
})
// r.onloadend = function(e){
// var data = e.target.result;
// console.log( "let data load", data );
// //send you binary data via $http or $resource or do anything else with it
// }
}
}
}
angular.module("tcpApp")
.directive('userPhotoUpload', userPhotoUpload );
In oreder to upload a data on http request you can do in different ways
as a file,as a byte array , binary but the easy way is as a file using the following method is thee file from the input
see here how to bind the directive with documendata variable
$http(
{ method: 'POST',
url: 'public/Game/store',
// headers: { 'content-type': 'multipart/form-data'},
data: documentData
});
You can do it with ng-flow's gallery upload
https://flowjs.github.io/ng-flow/

Save a file in angular from a http response

I was wondering how I can save a file that is contained in a response from the server in angular ? (So that the file is automatically downloaded when the response arrives)
Edit :
I have a $http post method, and I get pdf data in the response. On success, I want to save the response data as a pdf file.
E. g :
$http({
method: 'POST',
url : 'theUrl',
data: //some array that is received
headers : //content type info
}
.success(function(response) { // I want to save the response as a pdf });
On angular 2... you can do:
import { saveAs } from 'browser-filesaver/FileSaver.js'
downloadFile(data: Response) {
var blob = new Blob([data], {type: 'application/x-tar'});
saveAs(blob, "report.tgz");
}
Using HTML5 FileSaver interface, this can be achieved:
https://github.com/eligrey/FileSaver.js/
Example solution:
//Call API to retrieve file stream using POST request
$http.post("URL", searchData, { responseType: 'arraybuffer' }).then(
response => {
//Download file from response
saveFileAs(response);
},
data => {
//raise error
}
);
function saveFileAs(response) {
var contentDisposition = response.headers("content-disposition");
//Retrieve file name from content-disposition
var fileName = contentDisposition.substr(contentDisposition.indexOf("filename=") + 9);
fileName = fileName.replace(/\"/g, "");
var contentType = response.headers("content-type");
var blob = new Blob([response.data], { type: contentType });
saveAs(blob, fileName);
}
You can't save the document as you don't have access to the users file system in a browser. You could send the URL of the pdf back, then trigger the browsers build in file save / open mechanism by adding a dummy iFrame to the body:
$http({
method: 'POST',
url : 'theUrl',
data: //some array that is received
headers : //content type info
}
.success(function (data) {
if ($('#iframe').length == 0) {
var $iframe = $('<iframe id="iframe" style="display: none"></iframe>');
$('body').append($iframe);
}
$('#iframe').attr('src', {{url to retrieve the file}})
})

Resources