Sending FormData with AngularJS [duplicate] - javascript

I want to pass the username and form_data object to the php file using http.post
when i pass only form_data it works my picture upload. but i want to pass some other information like username as well. please help me how to pass other data in http.post
And here is my php file.
<?php include "connectdb.php";
$data=json_decode(file_get_contents("php://input"));
$name=$dbhandle->real_escape_string($data->susername);
if (!empty($_FILES)) {
$date=2;
$path = 'fooditem/'. $_FILES['file']['name'];
if (move_uploaded_file($_FILES['file']['tmp_name'],$path)) {
$query="INSERT INTO `login`(`id`,`type`,`img`) VALUES('".$name."','".$date."','".$_FILES['file']['name']."')";
if($dbhandle->query($query)){
echo 'File Uploaded';
}
else
echo 'File Uploaded But Not Saved';
}
}else{
echo 'Some Error';
}
myapp.directive("fileInput",function($parse){
return{
link: function($scope,element,attrs){
element.on("change",function(event){
var files = event.target.files;
$parse(attrs.fileInput).assign($scope, element[0].files);
$scope.$apply();
// console.log(files[0].name);
});
}
}
});
myapp.controller("myController",function($scope,$http){
$scope.signup = function(){
var form_data = new FormData();
angular.forEach($scope.files,function(file){
form_data.append('file',file);
});
$http.post("picupload.php",{'susername':$scope.susername,form_data})
.then(function(response){
console.log(response);
})
});
<input type="text" ng-model="username" name="username">
<input type="file" file-input="files" accept="image/*" />
<input type="submit" value="SIGN UP" ng-click="signup()"
name="signup_btn" class="btn btn-primary">

You can add something like this:
myapp.controller("myController",function($scope,$http){
$scope.signup = function(){
var form_data = new FormData();
angular.forEach($scope.files,function(file){
form_data.append('file',file);
});
form_data.append('susername',$scope.susername); // new line
var config = {headers: { 'Content-type': undefined } };
$http.post("picupload.php",form_data, config)
.success(function(response){
alert(response);
});
}
I'm not sure about PHP but after googling I found that in php 'susername' can retrieved as below:
$_POST['susername'];

How to make POST requests with the FormData API
When posting objects created by the FormData API, it is important to set the Content-type header to undefined.
$scope.signup = function(){
var form_data = new FormData();
angular.forEach($scope.files,function(file){
form_data.append('file',file);
});
form_data.append('susername', $scope.susername);
var config = {headers: { 'Content-type': undefined } };
return $http.post("picupload.php",form_data, config)
.then(function(response){
console.log(response.data);
return response.data;
});
};
Also a FormData object can not be serialized into a JSON string it must be sent by the XHR API alone. Append all necessary data to the FormData object.
When the XHR send API posts an object created by the FormData API, it automatically sets the content type header to multipart/form-data with a proper encapsulation boundary and encodes the data using base64 encoding.
Normally the $http service overrides the XHR API sets the content type header to application/json. Setting the content type header to undefined allows the XHR API the freedom to set the header properly.
Update
On the server side use:
$_POST['susername'];
to receive the data item.

Related

server side unable to capture append formdata files

I have a module where user can snap a picture (which will converted into a base64 string and then to a file), and I require to upload the file into our server, but after converted the base64 into file object and append it into formData and submit the form. I found that in my backend, it unable to read the $_FILES property (refer last image), the array is empty but which suppose to have my file in there.
And checking on my formData variable, the data is append into it.
html
<form id="form" method="POST" action="smth.php" enctype="multipart/form-data">
...
<!-- some other input information -->
</form>
js
$('#form').on('submit', function(){
...
var formData = new FormData($(this)[0]);
var base64 = $('#photo').attr('src');
console.log(...formData);
console.log('before checking');
if(base64 != 'default.png'){
var file = dataUrltoFile(base64, 'photo.png'); //external function to convert base64 into file object
formData.append('photo', file);
}
console.log('after checking');
console.log(...formData);
...
});
console
smth.php
<?php ... var_dump($_POST); var_dump($_FILES); exit(); ... ?>
result
You won't be able to attach your FormData instance to the existing <form> for a normal submit (I think).
If you want to mess with the normal submit, you'll need to add HTML elements into the <form> like <input type="file">.
Otherwise, submit the data via AJAX
document.getElementById('form').addEventListener('submit', async function(e) {
e.preventDefault()
const formData = new FormData(this)
// do stuff to formData
const res = await fetch(this.action, {
method: this.method,
body: formData // automatically sets Content-type: multipart/form-data
})
if (res.ok) {
// handle response
}
})

AngularJS - How to send an audio file through $http post?

So I've been trying to send an audio file through an $http service using FormData, and so far what I have tried to send the file hasn't worked yet.
This is how the service looks like:
songs_services.add_new_song = function(new_song_name, new_song_artist, song) {
var fd = new FormData();
fd.append("new_song_name", new_song_name);
fd.append("new_song_artist", new_song_artist);
fd.append("song", song);
console.log(fd.get("new_song_name"));
console.log(fd.get("new_song_artist"));
console.log(fd.get("song"));
return $http.post(BACKEND_PREFIX + "add_new_song", fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
}).then(function() {
}, function() {
});
};
I wanted to make sure that the information was actually been appended to my FormData and this is what i get in the console:
So now I know that the FormData has actually the information that I need.
I have also tried changing the Content-Type to multipart/form-data with no success also.
I'm also using CakePHP 2 as my backend, so this is how I'm trying to get the information:
public function add_new_song() {
$this->autoRender = false;
$data = json_decode(file_get_contents("php://input"));
print_r($data);
print_r($_POST);
print_r($_FILES);
$new_song_name = $_POST["new_song_name"];
$new_song_artist = $_POST["new_song_artist"];
$song = $_FILES;
echo $new_song_name;
echo "<br />";
echo $new_song_artist;
echo "<br />";
print_r($song);
die();
}
But echoing the variables only shows empty arrays and I also get an undefined index error when trying to access the variables from $_POST.
Is there any special way I should be sending the audio file through $http? I really feel like I'm missing a little detail.
At last, instead of using angularjs $http.post I decided to try with $.ajax and see what happened, and it actually worked!
Here's what I used:
$.ajax({
type : "post",
url : "uploads/songs",
data : fd,
cache : false,
contentType : false,
processData : false,
success: function() {
console.log("Hey");
}
});
And in Angular 6, you can do the following to send audio as FormData.
Inject the HttpClient:
constructor(private http:HttpClient){}
Use the POST method to send audio:
let url = 'http://destinationurl.com/endpoint';
let formData = new FormData();
formData.append('myAudioFile',audioFile);
this.http.post(url,formData).subscribe(response => {
//handle response
}, err => {
//handle error
});
the post method will automatically change the content type to multipart, so you need not set anything manually.

Uploading File via FormData

I am trying to upload a file to a Node backend that uses Multer. Multer requires the form to be submitted a specific way. If it's not submitted that way, the request.file parameter will be undefined. I have created an approach that works by using brute force. That working approach looks like this:
index-1.html:
<form method="POST" enctype="multipart/form-data" id="fileUploadForm">
<input type="file" id="selectedFile" name="selectedFile" /><br/><br/>
<input type="submit" value="Submit" id="btnSubmit"/>
</form>
...
var btn = document.getElementById('btnSubmit');
btn.addEventListener('click', function(e) {
e.preventDefault();
var form = $('#fileUploadForm')[0];
var data = new FormData(form);
console.log(data);
$.ajax({
type: "POST",
enctype: 'multipart/form-data',
url: "/upload",
data: data,
processData: false,
contentType: false,
cache: false,
timeout: 600000,
success: function (data) {
console.log("SUCCESS!");
},
error: function (e) {
console.log("ERROR : ", e);
}
});
});
The code above successfully posts the file to my server. That server has the following:
server.js
app.post('/upload', upload.single('selectedFile'), function(req, res) {
if (req.file) {
console.log('file uploaded');
} else {
console.log('no file');
}
res.send({});
});
Using the code above, "file uploaded" is displayed in the console window as expected. However, I need a more dynamic approach. For that reason, I need to programmatically build the form in JavaScript. In an attempt to do that, I've created the following:
index-2.html
[my UI]
var btn = document.getElementById('btnSubmit');
btn.addEventListener('click', function(e) {
var form = document.createElement('form');
form.action = '/upload';
form.method = 'POST';
form.enctype = 'multipart/form-data';
var node = document.createElement("input");
node.name = 'selectedFile';
node.value = GLOBAL_SELECTED_FILE;
form.appendChild(node);
var data = new FormData(form);
data.append('id', this.id);
console.log(data);
$.ajax({
type: 'POST',
url: '/profile-picture/upload',
enctype: 'multipart/form-data',
data: data,
contentType: false,
processData: false,
success: function(res) {
console.log('success!');
},
error: function(xhr, status, err) {
console.log('error');
}
});
});
This second approach does not work. To clarify, the GLOBAL_SELECTED_FILE variable is the data of a file that was selected from an input element. The data is loaded via the FileReader api. That looks like this:
var GLOBAL_SELECTED_FILE = null;
var fileReader = new FileReader();
fileReader.onload = function(e) {
GLOBAL_SELECTED_FILE = e.target.result;
}
fileReader.readAsDataURL(fileSelected); // file selected comes from the onchange event on a <input type="file">..</input> element
Basically, I'm loading a preview of the image. Anyways, when I hit the submit button in the working version (index-1.html), I notice in Fiddler that a different value is sent over the value sent in index-2.html.
With the approach in index-1.html, Fiddler shows something like this in the "TextView" tab:
------WebKitFormBoundary183mBxXxf1HoE4Et
Content-Disposition: form-data; name="selectedFile"; filename="picture.PNG"
Content-Type: image/png
PNG
However, when I look in the "TextView" tab in Fiddler for the data sent via index-2.html, I see the following:
------WebKitFormBoundary9UHBP02of1OI5Zb6
Content-Disposition: form-data; name="selectedFile"
data:image/png;base64,iVBORw0KGg[A LOT MORE TO GO]
It's like the FormData is using two different encodings for the same value. Yet, I don't understand why. How do I get index-2.html to send the image in the same format as index-1.html so that Multer will populate the req.file property?
Thank you!
In index-1.html, you are using a file input:
<input type="file" id="selectedFile" name="selectedFile" />
In index-2.html, you are creating an ordinary form input (not a file input):
var node = document.createElement("input");
node.name = 'selectedFile';
node.value = GLOBAL_SELECTED_FILE;
form.appendChild(node);
To create a file input, you would need to add node.type = 'file'. However, you won't be able to set the value because browser security restrictions prevent setting the value of file inputs.
Instead, what you need to do is append the file that was selected by the user to the FormData object:
var data = new FormData(form);
data.append('id', this.id);
data.append('selectedFile', $('#fileInputElement')[0].files[0]);

Submit dynamically created input from Angular to PHP Page

I am trying to create an invoice form, which can make all the necessary calculations like subtotal, tax total by itself .
Hitting the submit button should submit all values and the dynamically created items to a PHP page, which will insert these values (written by the user, or calculated by angularjs) to the appropriate SQL table/column as I wish.
Based on this project , I added this javascript code.
function PhpCtrl($scope, $http, $templateCache) {
var method = 'POST';
var url = 'added.php';
$scope.codeStatus = "";
$scope.add = function() {
var FormData = {};
$http({
method: method,
url: url,
data: FormData,
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
cache: $templateCache
}).
success(function(response) {
$scope.codeStatus = response.data;
}).
error(function(response) {
$scope.codeStatus = response || "Request failed";
});
return false;
};
}
Can anyone help me how to store all the dynamically created items, along with their values, in order to submit them to a php page ?
You can create a FormData to be submitted dynamically using plain javascript like this:
var fd = new FormData();
fd.append("fieldName", valueToSubmit);
fd.append("arrayField[]",[1,2,3]); //you can even post array data
The you push fd to the server:
var uri = "added.php";
var xhr = new XMLHttpRequest();
xhr.open("POST",uri,true);
xhr.onreadystatechange=function(){
if(xhr.readyState == 4 && xhr.status==200){
//do something with returned data
}
};
fd.append("img_file",blob_to_upload);// you can even upload a file
fd.append("user_id",data);
fd.append("category_id",category_id);
xhr.send(fd);

Upload a file with AngularJS and PHP

I want to upload a file while using AngularJS for frontend and PHP for backend.
When I would leave Angular aside, my HTML form would look like this:
<form enctype="multipart/form-data" action="process.php" method="POST" >
File: <input name="userfile" type="file"/>
<input type="submit" value="Send File" />
</form>
My PHP in process.php is this:
$tmpFilePath = $_FILES['userfile']['tmp_name'];
if ($tmpFilePath != ""){
$newFilePath = "my-uploads/" . $_FILES['userfile']['name'];
move_uploaded_file($tmpFilePath, $newFilePath);
}
So far, everything works fine, file is uploaded by clicking submit.
But I need the whole thing to be done with Angular. So I changed my HTML to this:
<form ng-submit="processForm()" >
File: <input name="userfile" type="file" ng-model="formData.file"/>
<input type="submit" value="Send File" />
</form>
The code inside my Angular-controller looks like this:
$scope.formData = '';
$scope.processForm = function() {
$http({
method : 'POST',
url : 'process.php',
data : $.param($scope.formData),
headers : { 'Content-Type': undefined }
})
.success(function(data) {
console.log(data);
console.log('success!');
})
.error(function(data) {
console.log(data)
});
};
When I click "submit", the console tells me "success!", but no file is uploaded. I think the problem is "data" and "headers" in th $http-request? But I'm really unsure about this and couldn't find a solution on the net so far. Does anybody know what I have to do to get my file uploaded while using angulars $http-functionality?
Angular can't upload files using AJAX without using the HTML5 file API.
Either change your code to use the file API and submit the binary content or use an external library such as angular-file-upload.
<input type='file' name="Filename" data-ng-file-select onchange="scope.setFile(this)" id="imgInp"> (html)
window.scope = $scope;
$scope.setFile = function (ele) {
var photofile = ele.files[0];
var reader = new FileReader();
console.log(photofile);
reader.onload = function (e) {
$scope.$apply(function () {
console.log(e);
$scope.prev_img = e.target.result;
$scope.prev_img = angular.copy($scope.prev_img);
$http({
method: 'POST',
url: 'api/1.php',
data: { 'imagepath': $scope.prev_img },
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' }
})
.success(function (data) {
console.log(data);
})
.error(function (error) {
$scope.data.error = error;
});
});
}; (angurlarjs)
<?php
include 'db_connect.php';
include 'functions.php';
//$levels = array();
$postdata = file_get_contents("php://input");
$request = json_decode($postdata);
$idUser = $request->imagepath;
echo $idUser;
// CLOSE CONNECTION
mysqli_close($mysqli);
echo json_encode($json);
?>(php)

Categories

Resources