Pass 2 parameters in $http POST - javascript

I have a scenario where a property can have multiple images but that image can only be assigned to one property(one to many, propertyId as FK).
In the html I'm retrieving the propertyId and passing it with the uploadFile function
<div id="imageDiv" ng-controller="uploadImageCtrl">
<input type="button" class="btn btn-info" value="Upload Image" ng-click="uploadFile(pro.id)"/>
<input type="file" file-input="files"/>
</div>
Here I have my app.js where I'm retrieving the image, and propertyId as Id. I'm trying to pass id and form_data.
app.directive("fileInput", function($parse){
return{
link: function($scope, element, attrs){
element.on("change", function(event){
var files = event.target.files;
console.log(files[0].name);
$parse(attrs.fileInput).assign($scope, element[0].files);
$scope.$apply();
});
}
}
});
app.controller("uploadImageCtrl", function($scope, $http,$routeParams,$location){
$scope.uploadFile = function(id){
var form_data = new FormData();
angular.forEach($scope.files, function(file){
form_data.append('file', file);
});
$scope.id = id;
console.log(id);
$routeParams.id = id;
//$scope.activePath = null;
$scope.updateMessage="";
console.log(form_data);
$http.post('php/uploadImage.php/',{'id':id},form_data,
{
transformRequest: angular.identity,
headers: {'Content-Type': undefined,'Process-Data': false}
}).success(function(response){
alert(response);
});
}
});
Then in uploadImage.php I'm assigning $id to the propertyId retrieved from app.j and uploading the image to that propertyId.
<?php
$data = json_decode(file_get_contents("php://input"));
$id=$data->id;
echo $id;
require_once("connection.php");
$conn = connectToDb();
if(!empty($_FILES))
{
$path = '../Images/' . $_FILES['file']['name'];
if(move_uploaded_file($_FILES['file']['tmp_name'], $path))
{
$insertQuery = "INSERT INTO tbl_images(imagePath , propertyId) VALUES ('".$_FILES['file']['name']."',$id)";
if(mysqli_query($conn, $insertQuery))
{
echo 'File Uploaded';
}
else
{
echo 'File Uploaded But not Saved';
}
}
}
else
{
echo mysqli_error($conn);
}
?>
The problem is that it's giving me a blank error with the number 8 and don't why it's not uploading, the 8 represents $id(echo $id).So propertyId is being retrieved succesfully and passed into the php.
The error is probably the last ELSE statment(echo mysqli_error($conn)).
Is form_data not being passed succefully?

I just needed to append id as well, with the form data and then retrieve the id with a normal POST.
app.controller("uploadImageCtrl", function($scope, $http,$routeParams,$location){
$scope.uploadFile = function(id){
var form_data = new FormData();
angular.forEach($scope.files, function(file){
form_data.append('file', file);
});
form_data.append('elmID', id);
$http.post('php/uploadImage.php',form_data,
{
transformRequest: angular.identity,
headers: {
'Content-Type': undefined,
'Process-Data': false
}
}).success(function(response){
alert(response);
});
}
});

Related

Laravel 8: AJAX Upload files using onchange

I want to upload multiple files using onchange in laravel 8. is it possible to upload just by onchange? I have this html form. I hope you can help me guys. thanks
<form method="POST" enctype="multipart/form-data" id="upload_form">
#csrf
<input type="file" name="file[]" id="file" multiple >
</form>
this is my Jquery and Ajax Script.
<script>
function uploadfile(){
var formData = new FormData($('#upload_form')[0]);
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
type:'POST',
url: "{{ route('dropzone-action') }}",
data: formData,
contentType: false,
processData: false,
success: (response) => {
if (response) {
this.reset();
alert('Image has been uploaded successfully');
}
},
error: function(response){
console.log(response);
$('#image-input-error').text(response.responseJSON.errors.file);
}
});
}
and here is my controller
function action(Request $request){
$request->validate([
'file' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
]);
if($request->hasFile('file')){
foreach($request->file as $file) {
$completeFileName = $file->getClientOriginalName();
$fileNameOnly = pathinfo($completeFileName, PATHINFO_FILENAME);
$extension = $file->getClientOriginalExtension();
$file->storeAs('uploads', $completeFileName);
}
}
return response()->json('Image uploaded successfully');
}
You can call change method
$("#file").change(function() {
uploadfile();
});
and in validation
$request->validate([
'file.*' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
]);
and in controller
function action(Request $request){
$request->validate([
'file.*' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
]);
foreach($request->file as $file) {
if($file!=null){
$completeFileName = $file->getClientOriginalName();
$fileNameOnly = pathinfo($completeFileName, PATHINFO_FILENAME);
$extension = $file->getClientOriginalExtension();
$file->storeAs('uploads', $completeFileName);
}
}
return response()->json('Image uploaded successfully');
}

CodeIgniter file upload error “You did not select a file to upload” using Ajax

I've seen and tried a few answers that are similar to this question, but it still displays the same error.
The console is also giving the error: Uncaught TypeError: Cannot read property 'length' of undefined at Function.each (jquery-1.10.2.js:631)
My view:
<form action="https://dev.vmc.w3.uvm.edu/xana/sensors/deployments" class="basicForm aboutForm form-horizontal" id="deploymentForm" enctype="multipart/form-data" method="post" accept-charset="utf-8">
<div class="form-group">
<label for="fldFileName" class="col-sm-4 control-label">Image</label>
<div class="col-sm-8">
<input type="file" name="fldFileName" value="" class="form-control" id="fldFileName" />
</div>
</div>
<button type="button" class="btn btn-primary" id="newSensorSubmit">Save</button>
</form>
javascript to submit form:
$(document).on("click", "#newSensorSubmit", function(event){
var posturl="<?php echo site_url("sensors/add_deployment");?>";
var formData = new FormData();
var fldFileName = $('#fldFileName').val();
formData.append('fldFileName', fldFileName);
jQuery.ajax({
url: posturl,
data: formData,
cache: false,
mimeType: "multipart/form-data",
dataType: 'json',
contentType: false,
processData: false,
type: 'POST',
success: function(data){
if(data.status === 'success') {
//handle success
}
else {
//handle fail
}
},
error: (error) => {
$('#articleErrorText').html(JSON.stringify(error));
}
});
});
controller:
public function add_deployment(){
$this->load->helper(array('form', 'url'));
$this->load->library('upload');
$config = array(
'upload_path' => site_url("attachments/project/999/metstations"),
'allowed_types' => "gif|jpg|png|jpeg",
'overwrite' => TRUE,
'max_size' => "16000000"
);
$this->load->library('upload', $config);
if($this->upload->do_upload('fldFileName'))
{
$data['image_metadata'] = array('image_metadata' => $this->upload->data());
}
else
{
$error = $this->upload->display_errors();
$data['errors']='<p class="error-message">'.$error.'</p>';
$data['status']='failure';
}
}
Try This.
To get all your form inputs, including the type="file" you need to use FormData object.
To append param just use append() method:
formData.append("param", "value");
And in the php-side I catch it:
echo $file_name = ($_FILES['file']['name']);
View Code:-
<body>
<p id="msg"></p>
<input type="file" id="file" name="file" />
<button id="upload">Upload</button>
</body>
jQuery / Ajax Code:-
<script type="text/javascript" src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function(e){
$('#upload').on('click', function () {
var file_data = $('#file').prop('files')[0];
var form_data = new FormData();
form_data.append('file', file_data);
$.ajax({
url: 'ControllerName/upload_file', // point to server-side controller method
dataType: 'text', // what to expect back from the server
cache: false,
contentType: false,
processData: false,
data: form_data,
type: 'post',
success: function (response) {
$('#msg').html(response); // display success response from the server
},
error: function (response) {
$('#msg').html(response); // display error response from the server
}
});
});
});
</script>
Controller Code:-
class ControllerName extends CI_Controller {
function __construct() {
parent::__construct();
}
function upload_file() {
//upload file
$config['upload_path'] = 'uploads/';
$config['allowed_types'] = '*';
$config['max_filename'] = '255';
$config['encrypt_name'] = TRUE; // remove it for actual file name.
$config['max_size'] = '1024'; //1 MB
if (isset($_FILES['file']['name'])) {
if (0 < $_FILES['file']['error']) {
echo 'Error during file upload' . $_FILES['file']['error'];
} else {
if (file_exists('uploads/' . $_FILES['file']['name'])) {
echo 'File already exists : uploads/' . $_FILES['file']['name'];
} else {
$this->load->library('upload', $config);
if (!$this->upload->do_upload('file')) {
echo $this->upload->display_errors();
} else {
echo 'File successfully uploaded : uploads/' . $_FILES['file']['name'];
}
}
}
} else {
echo 'Please choose a file';
}
}
}
Note:- For more reference regarding this check this
https://developer.mozilla.org/en-US/docs/Web/API/FormData/append

Using FormData to send Image to backend [duplicate]

I have a form with two input text and one upload. I have to send it to the server but I have some problem concatenating the file with the text. The server expects this answer:
"title=first_input" "text=second_input" "file=my_file.pdf"
This is the html:
<input type="text" ng-model="title">
<input type="text" ng-model="text">
<input type="file" file-model="myFile"/>
<button ng-click="send()">
This is the Controller:
$scope.title = null;
$scope.text = null;
$scope.send = function(){
var file = $scope.myFile;
var uploadUrl = 'my_url';
blockUI.start();
Add.uploadFileToUrl(file, $scope.newPost.title, $scope.newPost.text, uploadUrl);
};
This is the Directive fileModel:
return {
restrict: 'A',
link: function(scope, element, attrs) {
var model = $parse(attrs.fileModel);
var modelSetter = model.assign;
element.bind('change', function(){
scope.$apply(function(){
modelSetter(scope, element[0].files[0]);
});
});
}
};
And this is the Service which call the server:
this.uploadFileToUrl = function(file, title, text, uploadUrl){
var fd = new FormData();
fd.append('file', file);
var obj = {
title: title,
text: text,
file: fd
};
var newObj = JSON.stringify(obj);
$http.post(uploadUrl, newObj, {
transformRequest: angular.identity,
headers: {'Content-Type': 'multipart/form-data'}
})
.success(function(){
blockUI.stop();
})
.error(function(error){
toaster.pop('error', 'Errore', error);
});
}
If I try to send, I get Error 400, and the response is: Multipart form parse error - Invalid boundary in multipart: None.
The Payload of Request is: {"title":"sadf","text":"sdfsadf","file":{}}
Don't serialize FormData with POSTing to server. Do this:
this.uploadFileToUrl = function(file, title, text, uploadUrl){
var payload = new FormData();
payload.append("title", title);
payload.append('text', text);
payload.append('file', file);
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 use it:
MyService.uploadFileToUrl(file, title, text, uploadUrl).then(successCallback).catch(errorCallback);
Here is the complete solution
html code,
create the text anf file upload fields as shown below
<div class="form-group">
<div>
<label for="usr">User Name:</label>
<input type="text" id="usr" ng-model="model.username">
</div>
<div>
<label for="pwd">Password:</label>
<input type="password" id="pwd" ng-model="model.password">
</div><hr>
<div>
<div class="col-lg-6">
<input type="file" file-model="model.somefile"/>
</div>
</div>
<div>
<label for="dob">Dob:</label>
<input type="date" id="dob" ng-model="model.dob">
</div>
<div>
<label for="email">Email:</label>
<input type="email"id="email" ng-model="model.email">
</div>
<button type="submit" ng-click="saveData(model)" >Submit</button>
directive code
create a filemodel directive to parse file
.directive('fileModel', ['$parse', function ($parse) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
var model = $parse(attrs.fileModel);
var modelSetter = model.assign;
element.bind('change', function(){
scope.$apply(function(){
modelSetter(scope, element[0].files[0]);
});
});
}
};}]);
Service code
append the file and fields to form data and do $http.post as shown below
remember to keep 'Content-Type': undefined
.service('fileUploadService', ['$http', function ($http) {
this.uploadFileToUrl = function(file, username, password, dob, email, uploadUrl){
var myFormData = new FormData();
myFormData.append('file', file);
myFormData.append('username', username);
myFormData.append('password', password);
myFormData.append('dob', dob);
myFormData.append('email', email);
$http.post(uploadUrl, myFormData, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
.success(function(){
})
.error(function(){
});
}
}]);
In controller
Now in controller call the service by sending required data to be appended in parameters,
$scope.saveData = function(model){
var file = model.myFile;
var uploadUrl = "/api/createUsers";
fileUpload.uploadFileToUrl(file, model.username, model.password, model.dob, model.email, uploadUrl);
};
You're sending JSON-formatted data to a server which isn't expecting that format. You already provided the format that the server needs, so you'll need to format it yourself which is pretty simple.
var data = '"title='+title+'" "text='+text+'" "file='+file+'"';
$http.post(uploadUrl, data)
This never gonna work, you can't stringify your FormData object.
You should do this:
this.uploadFileToUrl = function(file, title, text, uploadUrl){
var fd = new FormData();
fd.append('title', title);
fd.append('text', text);
fd.append('file', file);
$http.post(uploadUrl, obj, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
.success(function(){
blockUI.stop();
})
.error(function(error){
toaster.pop('error', 'Errore', error);
});
}
Using $resource in AngularJS you can do:
task.service.js
$ngTask.factory("$taskService", [
"$resource",
function ($resource) {
var taskModelUrl = 'api/task/';
return {
rest: {
taskUpload: $resource(taskModelUrl, {
id: '#id'
}, {
save: {
method: "POST",
isArray: false,
headers: {"Content-Type": undefined},
transformRequest: angular.identity
}
})
}
};
}
]);
And then use it in a module:
task.module.js
$ngModelTask.controller("taskController", [
"$scope",
"$taskService",
function (
$scope,
$taskService,
) {
$scope.saveTask = function (name, file) {
var newTask,
payload = new FormData();
payload.append("name", name);
payload.append("file", file);
newTask = $taskService.rest.taskUpload.save(payload);
// check if exists
}
}
Assume that we want to get a list of certain images from a PHP server using the POST method.
You have to provide two parameters in the form for the POST method. Here is how you are going to do.
app.controller('gallery-item', function ($scope, $http) {
var url = 'service.php';
var data = new FormData();
data.append("function", 'getImageList');
data.append('dir', 'all');
$http.post(url, data, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
}).then(function (response) {
// This function handles success
console.log('angular:', response);
}, function (response) {
// this function handles error
});
});
I have tested it on my system and it works.

angularjs $http(config) ith data from form not working

I have an issue with $http in angularjs :
app.controller('ctrlProfil', function($scope, $http){
$scope.loginProfil = "<?= $_SESSION['login']?>";
$scope.mdpProfil = "<?= $_SESSION['mdp']?>";
$scope.emailProfil = "<?= $_SESSION['email']?>";
var config = {
method: 'POST',
url: 'modifProfil.php',
data: $('#formProfil').serialize()
}
$scope.submit = function(){
$http(config).
then(function(response){
console.log(response);
console.log($('#formProfil').serialize());
})
}
});
my form =>
<form id="formProfil" ng-submit="submit()">
<p><span>Bonjour </span><input type="text" name="loginProfil" value="{{loginProfil}}"/></p>
<p>Mon mot de passe: <input type="text" name="mdpProfil" value="{{mdpProfil}}"/></p>
<p> Email: <input type="email" name="emailProfil" value="{{emailProfil}}"/></p>
<input class="btn btn-primary" type="submit" value="Enregistrer"/>
</form>
my php code =>
try
{
$db = new PDO('mysql:host=localhost;dbname=monprojet;charset=UTF8', 'root', 'root');
}
catch(Exception $e)
{
die('Erreur : '.$e->getMessage());
}
$login = $_POST['loginProfil'];
$mdp = $_POST['mdpProfil'];
$email = $_POST['emailProfil'];
$rep = $db->query('SELECT id FROM utilisateur WHERE login='.$_SESSION['login']);
$reponse = $db->prepare('UPDATE utilisateur SET login= :login, mdp= :mdp, email= :email WHERE id='.$rep);
$reponse->execute(array(
':login' => $login,
':mdp' => $mdp,
':email' => $email
));
$json = json_encode($reponse->fetchAll());
$reponse->closeCursor();
echo $json;
i can't manage to send the data via the $http(config), i have an error telling me :
Notice: Undefined index: loginProfil in
/Applications/MAMP/htdocs/izad/git/modifProfil.php on line 15
Notice: Undefined index: mdpProfil in
/Applications/MAMP/htdocs/izad/git/modifProfil.php on line 17
Notice: Undefined index: emailProfil in
/Applications/MAMP/htdocs/izad/git/modifProfil.php on line 19
but my index are defined, need some help to understand this one
Thanks
You have to add headers application/x-www-form-urlencoded to receive the data in GET/POST request in php.
By default, the $http service will transform the outgoing request by
serializing the data as JSON
Change your $http request to this:
var config = {
method: 'POST',
url: 'modifProfil.php',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: $('#formProfil').serialize()
}
$scope.submit = function(){
$http(config).
then(function(response){
console.log(response);
console.log($('#formProfil').serialize());
})
You can also add headers for all $http request like this:
myapp.factory('httpRequestInterceptor', function () {
return {
request: function (config) {
config.headers['Content-Type'] = 'application/x-www-form-urlencoded';
return config;
}
};
});
myapp.config(function ($httpProvider) {
$httpProvider.interceptors.push('httpRequestInterceptor');
});

File upload via Ajax in Laravel

I'm trying to upload a file through ajax in Laravel.
$("#stepbutton2").click(function(){
var uploadFile = document.getElementById("largeImage");
if( ""==uploadFile.value){
}
else{
var fd = new FormData();
fd.append( "fileInput", $("#largeImage")[0].files[0]);
$.ajax({
url: '/nominations/upload/image',
data: fd,
processData: false,
contentType: false,
type: 'POST',
success: function(data){
if(data.uploaded==true){
alert(data.url);
}
},
error: function(err){
alert(err);
}
});
}
});
I'm passing the file input to the php script.
public function image(){
$file = Input::file('fileInput');
$ext = $file->getClientOriginalExtension();
$fileName = md5(time()).".$ext";
$destinationPath = "uploads/".date('Y').'/'.date('m').'/';
$file->move($destinationPath, $fileName);
$path = $file->getRealPath();
return Response::json(["success"=>true,"uploaded"=>true, "url"=>$path]);
}
I'm getting a the response as
{"success":true,"uploaded":true,"url":false}
The request Payload is
------WebKitFormBoundary30GMDJXOsygjL0ZS
Content-Disposition: form-data; name="fileInput"; filename="DSC06065 copy.jpg"
Content-Type: image/jpeg
Why this is happening?
Found the answer:
public function image(){
$file = Input::file('fileInput');
$ext = $file->getClientOriginalExtension();
$fileName = md5(time()).".$ext";
$destinationPath = "uploads/".date('Y').'/'.date('m').'/';
$moved_file = $file->move($destinationPath, $fileName);
$path = $moved_file->getRealPath();
return Response::json(["success"=>true,"uploaded"=>true, "url"=>$path]);
}
Get the path after assigning it to a new variable.

Categories

Resources