XMLHttpRequest - sending arrays by _POST - arrays

With the old $.ajax method I would send arrays and normal data like so:
var dataARR = {
byteValue: 1,
data: []
};
Note data is an array.
dataARR.data.push({Username: "wazo", Info: "wazoinfo"});
dataARR.data.push({Username: "bifo", Info: "bifoinfo"});
Then getting it ready and sending:
var dataJSON = JSON.stringify(dataARR);
$.ajax({
type: "POST", // This for array
url: "login.php",
cache: false,
data: { myJson: dataJSON },
success: function (data) {
// Do stuff here
}
});
In the php code I would then do the following:
$dataTotal = json_decode($post['myJson'], true);
$Username0 = $dataTotal['data'][0]['Username'];
$Info0 = $dataTotal['data'][0]['Info']);
$Username1 = $dataTotal['data'][1]['Username'];
$Info1 = $dataTotal['data'][1]['Info']);
All that worked well.
However, now I am changing to XMLHttpRequest:
var url = "login.php";
var method = "POST";
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
// XHR for Chrome/Firefox/Opera/Safari.
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined") {
// XDomainRequest for IE.
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
// CORS not supported.
xhr = null;
}
if (!xhr) {
return;
}
// Response handlers.
xhr.onload = function (data) {
// Do stuff
};
And the important bit
var dataJSON = JSON.stringify(dataARR);
xhr.send({ myJson: dataJSON });
But now the $_POST['myJson'] does not exist
When I do an echo print_r($_POST);, it returns Array()1
Question: What do I need to send in xhr.send(????); to get it so I can read the arrays in php again?

You access the data differently with XMLHttpRequest.
In the javascript:
var dataJSON = JSON.stringify(dataARR);
xhr.send(dataJSON);
In the php:
$dataTotal = json_decode(file_get_contents( "php://input" ), true);
$Username0 = $dataTotal['data'][0]['Username'];
$Info0 = $dataTotal['data'][0]['Info']);
$Username1 = $dataTotal['data'][1]['Username'];
$Info1 = $dataTotal['data'][1]['Info']);

Related

Three promises with HTTP

I had to do three HTTP Post requests in my code. The first two work, I debug the code and they return the correct value, but the last one returns undefined.
I made these three requisitions due to one depending on the response of the other.
login button:
goToMenu() {
this.dados_login = [];
this.dados_login.push({
"CPF": this.cpfLogin,
"Senha": this.senhaLogin
})
let headers = new Headers();
headers.append('Content-Type', 'application/json; charset=UTF-8');
let options = new RequestOptions({ headers: headers });
return new Promise((resolve, reject) => {
this.http.post(this.url, JSON.stringify(this.dados_login["0"]), options)
.toPromise()
.then((response) => {
var json_token = (response as any)._body;
var parsed = JSON.parse(json_token);
var arr = [];
for (var x in parsed) {
arr.push(parsed[x]);
}
this.token = arr[0];
this.carregaEmpresas();
})
.catch((error) => {
var json_error = (error as any)._body;
var parsed = JSON.parse(json_error);
var arr = [];
for (var x in parsed) {
arr.push(parsed[x]);
}
this.error_login = arr[0];
this.presentAlert(this.error_login)
});
});
function that carries companies, the error occurs here because it is not returned nothing to it
carregaEmpresas(newpage: boolean = false) {
console.log(this.cpfLogin);
this.abreCarregando();
return new Promise((resolve, reject) => {
this.EmpresaProvider.getEmpresas(this.token, this.cpfLogin)
.then((response) => {
var json_emp = (response as any)._body;
var parsed = JSON.parse(json_emp);
var arr_emp = [];
for (var x in parsed) {
arr_emp.push(parsed[x]);
}
this.lista_empresas = arr_emp;
this.objEmp = [];
for (let i = 0; i < this.lista_empresas.length; i++) {
this.obj = {
label:
this.lista_empresas[i].Valor,
type: 'radio',
value: this.lista_empresas[i].Chave
}
this.objEmp.push(this.obj);
}
this.fechaCarregando();
this.selectEmpresa();
})
.catch((error) => {
var json_error = (error as any)._body;
var parsed = JSON.parse(json_error);
var arr = [];
for (var x in parsed) {
arr.push(parsed[x]);
}
this.error_login = arr[0];
this.presentAlert(this.error_login)
});
});
provider role:
return new Promise((resolve, reject) => {
this.http.post(this.baseApiPath, JSON.stringify(this.cpf_usuario["0"]), options)
.toPromise()
.then((response) => {
var empresa = (response as any)._body;
var parsed = JSON.parse(empresa);
var arr = [];
for (var x in parsed) {
arr.push(parsed[x]);
}
this.empresa_cod = arr[0].Chave.split("/", 1);
var urlFilial = this.apiFilial + this.empresa_cod["0"];
return this.http.get(urlFilial, options);
})
.catch((error) => {
var json_error = (error as any)._body;
var parsed = JSON.parse(json_error);
var arr = [];
for (var x in parsed) {
arr.push(parsed[x]);
}
return arr[0];
});
});
GetEmpresas Code:
getEmpresas(token: string, Cpf: string) {
let headers = new Headers();
headers.append('Content-Type', 'application/json; charset=UTF-8');
headers.append('Authorization', 'bearer ' + token);
let options = new RequestOptions({ headers: headers });
this.cpf_usuario.push({ "Cpf": Cpf });
return new Promise(resolve => {
window.setTimeout(() => {
this.http.post(this.baseApiPath, JSON.stringify(this.cpf_usuario["0"]), options)
.toPromise()
.then((response) => {
var empresa = (response as any)._body;
var parsed = JSON.parse(empresa);
var arr = [];
for (var x in parsed) {
arr.push(parsed[x]);
}
this.empresa_cod = arr[0].Chave.split("/", 1);
var urlFilial = this.apiFilial + this.empresa_cod["0"];
return this.http.get(urlFilial, options)
.toPromise()
.then((response) => {
var json_emp = (response as any)._body;
var parsed = JSON.parse(json_emp);
var arr_emp = [];
for (var x in parsed) {
arr_emp.push(parsed[x]);
}
this.emp = arr_emp;
return arr_emp;
})
})
.catch((error) => {
var json_error = (error as any)._body;
var parsed = JSON.parse(json_error);
var arr = [];
for (var x in parsed) {
arr.push(parsed[x]);
}
return arr[0];
});
}, 2000);
});
}
This is a draft because I'm not sure I've found the problem yet, but I need to share more code than will fit in a comment.
The first thing I would try is removing the new Promise because you aren't resolving or rejecting those promises anyway. I'd also try removing the window.setTimeout. At that point, it looks like getEmpresas will return a promise for the arr_emp that is the result of parsing the final get response. If you do that, then the then handler in carregaEmpresas will receive the arr_emp that was generated in getEmpresas, so you should just name the parameter arr_emp and not try to parse it again. The code at this point is:
class MyClass {
// Dummy declarations to suppress TypeScript errors
dados_login;
cpfLogin;
senhaLogin;
http;
url;
token;
error_login;
presentAlert;
abreCarregando;
lista_empresas;
objEmp;
obj;
fechaCarregando;
selectEmpresa;
EmpresaProvider: EmpresaProvider;
goToMenu() {
this.dados_login = [];
this.dados_login.push({
"CPF": this.cpfLogin,
"Senha": this.senhaLogin
})
let headers = new Headers();
headers.append('Content-Type', 'application/json; charset=UTF-8');
let options = new RequestOptions({ headers: headers });
this.http.post(this.url, JSON.stringify(this.dados_login["0"]), options)
.toPromise()
.then((response) => {
var json_token = (response as any)._body;
var parsed = JSON.parse(json_token);
var arr = [];
for (var x in parsed) {
arr.push(parsed[x]);
}
this.token = arr[0];
this.carregaEmpresas();
})
.catch((error) => {
var json_error = (error as any)._body;
var parsed = JSON.parse(json_error);
var arr = [];
for (var x in parsed) {
arr.push(parsed[x]);
}
this.error_login = arr[0];
this.presentAlert(this.error_login)
});
}
carregaEmpresas(newpage: boolean = false) {
console.log(this.cpfLogin);
this.abreCarregando();
this.EmpresaProvider.getEmpresas(this.token, this.cpfLogin)
.then((/*response*/ arr_emp) => {
/*
var json_emp = (response as any)._body;
var parsed = JSON.parse(json_emp);
var arr_emp = [];
for (var x in parsed) {
arr_emp.push(parsed[x]);
}
*/
this.lista_empresas = arr_emp;
this.objEmp = [];
for (let i = 0; i < this.lista_empresas.length; i++) {
this.obj = {
label:
this.lista_empresas[i].Valor,
type: 'radio',
value: this.lista_empresas[i].Chave
}
this.objEmp.push(this.obj);
}
this.fechaCarregando();
this.selectEmpresa();
})
.catch((error) => {
var json_error = (error as any)._body;
var parsed = JSON.parse(json_error);
var arr = [];
for (var x in parsed) {
arr.push(parsed[x]);
}
this.error_login = arr[0];
this.presentAlert(this.error_login)
});
}
}
class EmpresaProvider {
// Dummy declarations to suppress TypeScript errors
cpf_usuario;
http;
baseApiPath;
empresa_cod;
apiFilial;
emp;
getEmpresas(token: string, Cpf: string) {
let headers = new Headers();
headers.append('Content-Type', 'application/json; charset=UTF-8');
headers.append('Authorization', 'bearer ' + token);
let options = new RequestOptions({ headers: headers });
this.cpf_usuario.push({ "Cpf": Cpf });
return this.http.post(this.baseApiPath, JSON.stringify(this.cpf_usuario["0"]), options)
.toPromise()
.then((response) => {
var empresa = (response as any)._body;
var parsed = JSON.parse(empresa);
var arr = [];
for (var x in parsed) {
arr.push(parsed[x]);
}
this.empresa_cod = arr[0].Chave.split("/", 1);
var urlFilial = this.apiFilial + this.empresa_cod["0"];
return this.http.get(urlFilial, options)
.toPromise()
.then((response) => {
var json_emp = (response as any)._body;
var parsed = JSON.parse(json_emp);
var arr_emp = [];
for (var x in parsed) {
arr_emp.push(parsed[x]);
}
this.emp = arr_emp;
return arr_emp;
})
})
.catch((error) => {
var json_error = (error as any)._body;
var parsed = JSON.parse(json_error);
var arr = [];
for (var x in parsed) {
arr.push(parsed[x]);
}
return arr[0];
});
}
}
Please try this code (integrated into your original program of course) and let me know if it works or otherwise what is the exact error and what line it occurs on.

Angular ng-file-upload Get Byte Array and FormData in Asp.net MVC

I am trying to use ng-file-upload to upload files using Angular. I need the byte array to store in our database (I cannot store the uploaded file on the server), but I also need the FormData as well. My problem is that I can only seem to get one or the other (either the byte array or the formdata) but not both.
Here is my Angular code:
$scope.uploadPic = function (file) {
$scope.emrDetailID = 7;
file.upload = Upload.upload({
url: '/SSQV4/SSQV5/api/Document/UploadEMRDocument',
method: 'POST',
data: { file: file, 'emrdetail': $scope.emrDetailID}
});
file.upload.then(function (response) {
$timeout(function () {
file.result = response.data;
$scope.imageID = file.result;
});
});
};
Using the code below, I can get the byte array and store it in my database:
public async Task<IHttpActionResult> UploadDocument()
{
var provider = new MultipartMemoryStreamProvider();
await Request.Content.ReadAsMultipartAsync(provider);
var f = provider.Contents.First(); // assumes that the file is the only data
if (f != null)
{
string ClientIP = IPNetworking.GetIP4Address();
var filename = f.Headers.ContentDisposition.FileName.Trim('\"');
filename = Path.GetFileName(filename);
var extension = Path.GetExtension(filename).TrimStart('.');
var buffer = await f.ReadAsByteArrayAsync();
FileImageParameterModel pm = new FileImageParameterModel();
pm.binFileImage = buffer;
//pm.CompanyID = UserInfo.intMajorID;
pm.CompanyID = 10707;
pm.dteDocumentDate = Convert.ToDateTime("4/4/2016");
pm.dteExpiration = Convert.ToDateTime("4/4/2017");
pm.vchUserIP = ClientIP;
pm.vchUploadedbyUserName = UserInfo.Username;
pm.vchFileExtension = extension;
CommonClient = new CommonWebApiClient();
CommonClient.AuthorizationToken = UserInfo.AccessToken;
int imageID = await CommonClient.InsertNewFileImage(pm);
return Json(imageID);
}
else
{
return BadRequest("Attachment failed to upload");
}
}
Using the code below I can get the FormData
var provider = new MultipartFormDataStreamProvider(workingFolder);
await Request.Content.ReadAsMultipartAsync(provider);
var emr = provider.FormData["emrdetail"];
but then I can't get the byte array as using MultipartFormDataStreamProvider wants a folder to store the file.
There's got to be a way to get both. I have been searching the internet for 2 days and all I can find are the two solutions above neither of which solves my issue.
Any assistance is greatly appreciated!
You are thinking way to complicated. Here is some of my code which I used for file upload in AngularJS with .NET
Angular:
function uploadFileToUrl(file) {
var formData = new FormData(); // Notice the FormData!!!
formData.append('uploadedFile', file);
return $http({
url: uploadUrl,
method: 'POST',
data: formData,
headers: {
'Content-Type': undefined
}
}).then(resolve, reject);
function resolve(data) {
$log.debug('data : ', data);
return data;
}
function reject(e) {
$log.warn('error in uploadFileToUrl : ', e);
return $q.reject(e);
}
}
Server:
public Task HandleAsync([NotNull] UploadFilesCommand command)
{
return wrapper.InvokeOnChannel(async client =>
{
// init command
command.Output = new Dictionary<string, int>();
try
{
foreach (var file in command.Files)
{
var request = new UploadFileRequest
{
FileName = file.Name,
FileStream = file.Stream
};
UploadFileResponse response = await client.UploadFileAsync(request);
command.Output.Add(file.Name, response.Id);
}
}
finally
{
// dispose streams
foreach (var file in command.Files)
{
if (file.Stream != null)
{
file.Stream.Dispose();
}
}
}
});
}

How to send object that contains array via AJAX POST in Django

I am trying to send a object with an array inside of it via an AJAX POST in Django when the user clicks a button. I am following the instructions on the Django docs have hit a snag. I am attempting to see a specific indice in the array using logger.debug() in the view and am not able to access the contents. How do I access that specific element in the array?
My AJAX...
var tags_selected = [1,2,3,4]
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken = getCookie('csrftoken');
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
$("#filter").click(function(){
$.ajax({
type: 'POST',
url: "/pensieve/filtertags",
data: {'tags': tags_selected},
success: function(res){
console.log(res)
},
dataType: "json"
});
})
My View...
def filter_tags(request):
logger.debug(request.POST)
return HttpResponse(json.dumps({'response': 111}), content_type="application/json")
My DEBUG log in my terminal...
DEBUG - 2016-05-06:17:15:50 - <QueryDict: {u'tags[]': [u'142', u'122', u'138']}>
You can get values of the tags[] Array with getlist() method.
Example :
request.POST.getlist('tags[]')
# outputs : ['1', '2', '3']
request.POST.getlist('tags[]')[1]
# outputs : '2'

Saving Location of Scraped Image to DB - Node/MEAN

After scraping an image I'm able to download to a folder using request. I would like to pass along the location of this image to my Mongoose collection.
In the callback I think there should be a way to save the location so I can pass this along when saving my model object.
exports.createLook = function(req, res) {
var url = req.body.image;
var randomizer = '123456';
var download = function(url, filename, callback) {
request(url)
.pipe(fs.createWriteStream(filename))
.on('close', callback);
};
download(url, '../client/assets/images/' + randomizer + '.jpg', function() {
console.log('done');
// do something?
});
// now get model details to save
var newLook = new Look();
newLook.title = req.body.title;
newLook.image = // image location
newLook.save(function(err, look) {
if(err) return res.send(500);
} else {
res.send(item);
}
}
Assuming that 'randomizer' will be generated I would do:
exports.createLook = function(req, res) {
var url = req.body.image;
var randomizer = getSomthingRandom();
var download = function(url, filename, callback) {
request(url)
.pipe(fs.createWriteStream(filename))
.on('close', callback(filename);
};
download(url, '../client/assets/images/' + randomizer + '.jpg', function(filename) {
console.log('done');
// now get model details to save
var newLook = new Look();
newLook.title = req.body.title;
newLook.image = filename;
....
});

Multiple Queries with Parse Cloud Code Using Promises

I have two questions:
Is the below example the right way to execute multiple Parse queries in a single Cloud Code function?
Is the below example going to provide all the data I'm querying with one HTTP request (when I call logbookEntries) and then count as two Parse requests on my account because it's two Parse queries?
Here's the code:
Parse.Cloud.define("logbookEntries", function(request, response) {
//::: Query 1 :::
var firstQuery = new Parse.Query("Logbook");
var returnData = [];
firstQuery.find().then(function(firstResults) {
returnData[0] = firstResults;
}).then(function(result) {
//::: Query 2 :::
var secondQuery = new Parse.Query("Logbook");
secondQuery.find().then(function(secondResults))
returnData[1] = secondResults;
}).then(function(result) {
response.success(returnData);
}, function(error) {
response.error(error);
});
});
Thanks in advance.
It's one way, though not quite correct.
Yes
Your code should really be:
Parse.Cloud.define("logbookEntries", function(request, response) {
//::: Query 1 :::
var firstQuery = new Parse.Query("Logbook");
var returnData = [];
firstQuery.find().then(function(firstResults) {
returnData[0] = firstResults;
var secondQuery = new Parse.Query("Logbook");
return secondQuery.find();
}).then(function(result) {
returnData[1] = result;
response.success(returnData);
}, function(error) {
response.error(error);
});
});
Or, a better way to structure it would be:
Parse.Cloud.define("logbookEntries", function(request, response) {
var firstQuery = new Parse.Query("Logbook");
var secondQuery = new Parse.Query("Logbook");
var promises = [];
promises.push(firstQuery.find());
promises.push(secondQuery.find());
Parse.Promise.when(promises).then(function(result1, result2) {
var returnData = [];
returnData[1] = result1;
returnData[2] = result2;
response.success(returnData);
}, function(error) {
response.error(error);
});
}
Just to update Wain's structured code:
Promise.when returns array when supplied with an array, so the correct code would be
Parse.Promise.when(promises).then(function([result1, result2]) {
and since there is no need to repack the array, it would simply be
Parse.Promise.when(promises).then(function(result) {
response.success(result);
See here for more info.

Resources