Sending a file and json data with AJAX - javascript

I have tried two methods of sending the file and json data from client side over to server side. I been partially successful with both methods, I could use some help on completing this. I have two methods:
Method 1: I am able to access the file server side, but my form data (input, select, textarea) are not available to access.
Method 2: Appends the data to the formData object. The issue with method one is that I got it to work the other day, but I believe my browser cached the code and now its not working, so I feel like im back at step one. I am able to access the data by using request.data, but its bytes. The code that was working (request.form['json_data'] or request.files['file'].read()) and now its not working.
Client Side Code:
$('form[name="upload-form"]').on('submit', (event) => {
event.preventDefault();
$('#form-loader').fadeIn()
// Method 1
// let formData = new FormData($('#upload-form')[0]);
// Method 2
let entry = get_form_entry('upload-form'); -> UDF to get all form data. Iterates each form data and applies .val() and creates a dict.
const formData = new FormData();
formData.append('json_data', JSON.stringify(entry));
formData.append('file', $('#file')[0].files[0]);
$.ajax({
data: formData,
url: '/newEntry',
type: 'POST',
contentType: false,
processData: false,
cache: false,
success: function () {
$('#form-loader').fadeOut()
},
error: function () {
$('#form-loader').fadeOut()
},
})
})
Server Side Code:
json_data = request.form['json_data']
# json_data = request.data
file_data = request.files['file'].read()

Related

PUT type request with a file in AJAX arrives without data

I am making a request in a Laravel form (Blade).
To create the object I use a POST type request but to modify it I use a PUT type request.
I have to use AJAX and I have to send a file in the same request.
I have searched for information and with the POST type, it works correctly, but with the PUT type the request is empty.
I have been researching and testing and I have realized that the problem comes from this line of code within my "processData: false," request.
The problem is that if I don't put this line I get the error "Uncaught (in promise) TypeError: Illegal invocation".
That it was the same error that appeared in the POST request, so searching the internet I solved it like this.
Could someone help me to make the PUT request with the attached file?
My code:
const type_request = 'PUT';
const url_request = '{{ route('put_update_login', ['client' => $client, 'id' => $login->id]) }}';
let data_form = new FormData(document.getElementById(id_form));
$.ajax({
type: type_request,
url: url_request,
data: data_form,
dataType: "json",
processData: false,
contentType: false,
success: function(response) {
if (response.hasOwnProperty("route")) {
window.open(response['route'], "_self").focus();
} else {
$('#alert_error').removeAttr('hidden');
$("#alert_error").fadeTo(20000, 500000);
let errors = response['errors'];
$.each(errors, function (index, value) {
$("#alert_error").last().html(value);
});
$(':button').prop('disabled', false);
$('#spinner_form').prop('hidden', true);
}
}
});
The differences between the POST and PUT version is the "type_request" and the "url_request".
Thanks in advance

Javascript Equivalent of Swift HTTPbody

I am looking for a way to put variables in to a AJAX get call, now i know the obvious way to do it would just be to add it too "data" like so
$.ajax({
type: "get",
url: "api.php",
data: {sessionkey: sessionkey, request: 'createapplication', favourid: favourid, userid: userid, message:message },
success: function(data) {
console.log(data);
}
});
But this goes to an api and the api also handles request from an iOS app which put the data into httpBody like so
let json: [String: Any] = ["userid":userID, "message":applicationtext.text, "favourid":selectedFavour]
let jsondatatosend = try? JSONSerialization.data(withJSONObject: json)
// create post request
let url = "myurl";
var request = URLRequest(url: url)
request.httpMethod = "POST"
// insert json data to the request
request.httpBody = jsondatatosend
I believe the reason i did this origionally was it was messing up because of having strange characters in the URL so i had to send it through the body which all worked well, but now im trying to get a website to follow the same method on my api i would like it to be sent in the body from ajax so my php can do this function
$inputJSON = file_get_contents('php://input');
$input = json_decode($inputJSON, TRUE);
I understand there are many ways for me to get around it in my php just use $_GET[' var '] instead of file_get_contents when it is sent from the AJAX of my website but i was wondering if there was a way of sending it into the body via ajax so i dont have to change the php file and then it is not sent through url's
so what i want to be able to do is something like this
$.ajax({
type: "get",
url: "api.php",
data: {sessionkey: sessionkey, request: 'createapplication'},
httpBody: {favourid: favourid, userid: userid, message:message },
success: function(data) {
console.log(data);
}
});

Upload Attachment and some additional parameters to MVC Controller

I have a MVC Controller with the following signature:-
[HttpPost]
public async Task<JsonResult> SaveBrochureAsAttachment(Guid listingId, HttpPostedFileWrapper attachmentFile)
{
///some logic
}
How do I make an ajax call and send the file attachment and additional listingId parameter. Currently I am only able to send the attachment like this:-
var uploadFile = function () {
if ($('#attachmentFile').val()) {
}
else {
alert('No File Uploaded');
return;
}
var formData = new FormData($('#uploadForm')[0]);
$.ajax({
url: '/Listing/SaveBrochureAsAttachment',
type: 'POST',
data: formData,
async: false,
success: function (data) {
alert('File Uploaded');
},
error: function (jqXHR, textStatus, errorThrown) {
$("#FileUpload").replaceWith($("#FileUpload").val('').clone(true));
alert('File Uploaded Error');
},
cache: false,
contentType: false,
processData: false
});
return false;
}
Currently as you folks can see I am only able to send the attachment. How do I also send the Guid listingId to match the controller signature.
Try adding another formdata parameter:
formData.append("listingId", guidValue);
Provided you have the guid value accessible. You can use this to generate one from the client. Or create one from the server:
var guidValue = '#Guid.NewGuid()';
one approach would be to your controller accept viewmodel (a class) which contains different property you need. and use formdata.append required stuff to post to the server.
On Server side; you will need to use modelbinder so that you will get required stuff populated.
Refernce for modelbinder : https://www.dotnetcurry.com/aspnet-mvc/1261/custom-model-binder-aspnet-mvc
you can get more on google. :)

Store FormData object on localStorage HTML5

I'm trying to save some data to localStorage on my offline application. When user on offline mode, then browser will collect data from form, FormData object, store it to localStorage and when browser is online then it will push the FormData object that store in localStorage to server via jQuery ajax. The complexity is that the form have dynamic fields and can have the fileupload field and the problem is that the localStorage on html5 support data as string and not the object.
Collection.prototype.storeOfflineData = function(collectionId){
var formData = new FormData($('form')[0]);
pendingSites = {"collectionId" : collectionId, "formData" : formData};
window.localStorage.setItem("offlineSites", JSON.stringify(pendingSites));
Collection.prototype.goHome();
Collection.prototype.showErrorMessage("Successfully store data in offline.");
}
When the browser is online,connected to internet, I created the methods to read FormData from local storage and make ajax request to server but ajax request got error because the JSON.parse return "[object object]"
Collection.prototype.pushingPendingSites = function(){
pendingSites = JSON.parse(window.localStorage.getItem("offlineSites"));
if(pendingSites != null){
console.log(pendingSites[i]["formData"]);
Collection.prototype.ajaxCreateSite(pendingSites[i]["collectionId"], pendingSites[i]["formData"]);
}
}
Collection.prototype.ajaxCreateSite = function(collectionId, formData){
$.ajax({
url: '/mobile/collections/' + collectionId + '/sites', //Server script to process data
type: 'POST',
success: function(){
Collection.prototype.goHome();
Collection.prototype.showErrorMessage("Successfully saved.");
},
error: function(data){
Collection.prototype.showErrorMessage("Save new site failed!");
},
data: formData,
cache: false,
contentType: false,
processData: false
});
}

YUI3 io-upload-iframe

Can you use yui3's io-upload-iframe to send form data along with the file upload? I am setting the form's id, like I normally would to serialize the form data, but since I am setting upload : true, it doesn't seem to pass any form data with the request. Here is the code I am using.
var cfg = {
method: 'POST',
form: {
id: Y.ong('#myform'),
upload: true
}
};
var request = Y.io(requestURL, cfg);

Categories