How to send file details to back end using angularjs? - javascript

Hi I am developing web application in angularjs. I am developing file upload module. I have below array with file details.
//below code to get array of files
$scope.showPicker=function()
{
var client = filestack.init('AGeDIRvVZTRWgtmFbfGuZz');
client.pick({
}).then(function (result) {
arrMakes.push(result.filesUploaded);
});
}
In the above image i shown my array. I have three files.
Below is my angular code to send details to api.
var files = new FormData();
angular.forEach(arrMakes, function (value, index) {
console.log(value,index);
files.append(index, value);
files.append('data', angular.toJson(index).replace(/['"]+/g, ''));
});
return $http.post(this.uploadUrl, files, {
transformRequest: angular.identity,
headers: {
'Content-Type': undefined,
}
})
The problem is i am not receiving file in server side. Below line gives me 0 files in server.
System.Web.HttpFileCollection hfc = System.Web.HttpContext.Current.Request.Files;
May i know am i sending correct data to server? Can someone help me to fix this? Any help would be greatly appreciated. Thank you.

You are not uploading any files to the server, only strings.
You can't append objects to a FormData. appart from Blob & File objects See what will happen:
fd = new FormData
fd.append(2, {foo: 'bar'})
fd.append('data', 5)
new Response(fd).text().then(console.log)
// you get [object Object]
Why do you stringify the index in "data"? It will be casted to string automatically. And what is there that you have to replace?
If i where you i would just simple send the hole arrMakes to the server and download all the files from the url on the backend, otherwise the client has to download and then upload them to the server and wasting bandwidth and time.
beside, you don't need angulars forEach loop, arrays has that method built in
arrMakes.forEach(function (value, index) {
...
})
You won't even have to use any loop if you just pass the arrMarks to the server

Related

Does there exist a 'good-practice' way to send files without relying on FormData?

I'm currently working on an app with a React Native front-end and Node.js/Express backend. I am perfectly able to upload files using FormData with Content-Type multipart/form-data. The problem I have is that when using FormData, any other data that you wish to send in the body of the request is necessarily converted to a string. This isn't the case when one simply sends a JS object as the body of the request (as long you parse it on the backend of course). I wish to know if there is a good-practice way to send a file/files alongside JSON in a request, without losing the typings of said JSON?
Thanks
Add your data as JSON in a field of the FormData:
const data = {
foo: ["bar", 1]
};
const file = new File(["some content"], "myfile.txt");
const formdata = new FormData();
formdata.append("file", file);
// Send as JSON
formdata.append("data", JSON.stringify(data));
const req = new Request("./", { method: "POST", body: formdata });
// simulate server side getting the response
req.formData().then( (fd) => {
const received_file = fd.get("file");
// parse JSON
const received_data = JSON.parse(fd.get("data"));
console.log({ received_file, received_data });
});
When you insist on sending the image along with other data inside the JSON, then AFAIK your only option is to convert the image to some data type which can be transmitted via JSON.
The most obvious choice would be a string, and what is usually used here is the base64 encoding. It is, however, not very efficient and can cause lag.
What is sometimes done to stay within the JSON domain but still being able to upload images is to create two endpoints. One for the JSON data. One for the image upload in a binary format.

Upload files with Angular for PHP

I'm trying to upload a file using Angular (currently Angular 4).
But I'm unable to send it correctly. The best I can do is sending the file as a raw content (available in $_POST as some binary mess like this: )
ëPNG\r\n
\x1A\n
\x00\x00\x00\rIHDR\x00\x00\x00©\x00\x00\x008\x08\x06\x00\x00\x00Nâ2\x1F\x00\x00\n
óiCCPICC
What I want is the file to be uploaded and available in $_FILES variable in PHP.
Currently, I'm using this code in Angular
let picture = event.target.files[0];
let content = new FormData();
content.append('picture', picture, picture.name);
let headers = new Headers({'Accept': 'application/json',
'X-AUTH-TOKEN': this.user.token,
'Content-Type': picture.type});
let options = new RequestOptions({headers: headers});
this.http.post(Config.API_URL + `/user/profile/update/`, value, options).subscribe(response => {
console.log(response);
});
Currently, PHP code is just a var_dump($_FILES);
I think my problem may be related to the way Angular transforms the request.
I know there war a transformRequest option in AngularJS but I can't find how it works with Angular 4.
Do you have any suggestion on how I can make this work?
Thanks.

Creating Blob object from raw file downloaded from server with $http.

On server there is url with files stored.
Url is http://website.com/abc
I do $http get on this url.
$http.get(url, { responseType: "arraybuffer" });
I want to create Blob object from this. I am sure that object is of type png, because it had this extension before upload and it shows properly.
new Blob(result.data, {type: "image/png"});
I get message:
Failed to construct 'Blob': The 1st argument is neither an array, nor does it have indexed properties.
Response from server http://website.com/abc GET in developer console looks like:
ÿØÿàJFIFÿþ;CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), quality = 60
ÿÛC

 ' .)10.)-,3:J>36F7,-#WAFLNRSR2>ZaZP`JQROÿÛC&&O5-5OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOÿÂÒ"ÿÄÿÄÿÚæå2ag\Ý#úDê3[Zdfc5±Ô¢¬æ)K<`¤l2¸ÊánYR±aA`Í%RÈfbz!¤tÞÑ-µd7ZªÀ[hz¨f¥>©cAV¬{3á R³F0 W>~c³"ðÈìøÖ²ÇBÙ³±+
½ò9tµ°õ
I tried to set Blob type to application/octet-stream and also do $http.get without specified responseType.
How can I create a proper Blob file?
I need Blob File, to create File object which is an entry data to implemented logic to display files in slideshow with modals. I have implemented logic for files of type File, which were created by input forms - implementation was done for a need before uploading to server. Now it turns out that server doesn't return same files to me, but return only urls of files, which created an idea to convert from url to File in order to dont repeat in that logic.
Try
$http.get(url, { responseType: "blob" });
or
// missing `[]` at `js` at Question
new Blob([result.data], {type: "image/png"});
Note XMLHttpRequest responseType could also be set to "blob", see How to build PDF file from binary string returned from a web-service using javascript

AngularJs File Upload without FormData

I've made a simple drag and drop directive for file uploading, but my main concern is that i need to have IE8/9 support, so taking in account that FormData is not supported, how can i do a multiple file upload without using the FormData object?
Thanks in advance.
EDIT:
What i'm trying do do is this:
$scope.uploadFile = function () {
var upload = $http.post('awesomeFileThatWantsMultipleFilesUploaded.php',
angular.element(document.getElementsByClassName('droppable')).scope().files,
{withCredentials: true,
headers: {'Content-Type': undefined },
transformRequest: angular.identity})
.success(function (response) {
});
return upload;
}
But the problem is that when the browser doesn't have support for FormData, i initialize the files variable as array, and then i push each file to the variable. If the file is FormData, this works.
Don't make this by hand. Is rather messy and you will always have problems. You can use a polyfill for formdata, like moxie, for angular I use angular-file-upload there is even a way to upload to S3 from the browser (here)
If you want to do it by hand, check the code in those repositories and find some ideas

How to create an in memory file and upload to server using client side javascript?

I have a test suite written in JavaScript running in a browser that runs on an embedded system. The test suite collects a lot of data and I want to push that to the server. I could use a simple HttpRequest, post-method, but that would require a lot of character escaping to send the content. It would much simpler to upload it to the server as a file using http-file-upload.
Is there a way to create an in memory file and use http-file-upload to push it to a server, using client-side JavaScript?
Since the browser of the embedded system is Ekioh and the system itself is a minimal one, technologies such as flash, JavaApplet, SilverLight are not available. Only pure HTML5 and JavaScript are available.
I think a post would be the better way to do this. Dealing with escaped data is a much easier, more established problem then in-memory files and pushing files to the server with client side javascript. Moreover, escaping data is done for a reason. What you're trying to do is going to welcome a lot of security vulnerabilities.
Try doing something like this.
Snippet taken from Write javascript output to file on server
var data = "...";// this is your data that you want to pass to the server (could be json)
//next you would initiate a XMLHTTPRequest as following (could be more advanced):
var url = "get_data.php";//your url to the server side file that will receive the data.
http.open("POST", url, true);
//Send the proper header information along with the request
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.setRequestHeader("Content-length", params.length);
http.setRequestHeader("Connection", "close");
http.onreadystatechange = function() {//Call a function when the state changes.
if(http.readyState == 4 && http.status == 200) {
alert(http.responseText);//check if the data was revived successfully.
}
}
http.send(data);
This worked for me. The key part is to create a file and blob. I use angular JS to do the actual http call. However, once you have a file in memory, it shouldn't be too hard to send the data using your http client.
Note: I do the http call to https://httpbin.org/post. This echoes what the server received/parsed, which is useful while iterating to figure your problem out.
function multiPartPost(bodyObj) {
const url = 'https://httpbin.org/post';
const bodyJson = JSON.stringify(bodyObj);
const blob = new Blob([bodyJson], {
type: 'application/json;charset=UTF-8'
});
const fileName = 'jsonAttrs';
const file = new File([blob], fileName, {type: "text/json;charset=utf-8"});
const formData = new FormData();
formData.append(fileName, file);
return this.$http.post(url, formData, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
});
}

Categories

Resources