Getting empty response from Titanium getResponseData() where there should be data - appcelerator

I'm trying to get a response from a third party server. If I try to get the response from postman. I get an array of objects. So it does work, I'm pretty sure it does actually. However when I try to do it on my app it returns this empty array:
LOG:
[INFO] : SUCCESS AddressAddressListGet
[INFO] : Status code 200
[INFO] : DATA response: []
[INFO] : Text response: []
[INFO] : Todos os HEADERS Transfer-Encoding:Identity
[INFO] : Content-Type:text/plain; charset=utf-8
[INFO] : Server:Microsoft-HTTPAPI/2.0
[INFO] : Date:Wed, 28 Mar 2018 20:36:49 GMT
[INFO] : Connected? false
[INFO] : Type of connection GET
Here's the actual CODE:
var httpRequest = function(url, timeout, _headers, method, _data, onSuc, onErr)
{
var client = Ti.Network.createHTTPClient({
onload: onSuc,
onerror: onErr,
timeout: timeout //5000
});
client.open(method, url);
if (_headers.length != 0 && _headers != 0){
for (var key in _headers) {
client.setRequestHeader(key, _headers[key]);
if (_data.length != 0 && _data != 0)
{
client.send(JSON.stringify(_data));
} else {
client.send();
}
}; //END OF FUNC HTTPREQUEST()
var AddressAddressListGet = function(onSuc, onErr, accountId) {
if(typeof(accountId) == 'undefined' || accountId == 0)
{
var url = urlAddressAddressListGet + "?accountId=" + accountId;
}
else {
var url = urlAddressAddressListGet;
}
var header = {
"Content-Type": "application/json",
"Authorization": Ti.App.TOKEN
};
var _data = 0;
httpRequest(url, TIMEOUT, header, "GET", _data, onSuc, onErr);
}; //AddressAddressListGet
Here's my on success callback function:
var onsucAddressAddressListGet = function(e) {
console.log('SUCCESS AddressAddressListGet');
console.log("Status code " + this.getStatus());
console.log("DATA response: " + this.getResponseData());
console.log("Text response: " + this.getResponseText());
console.log("Todos os HEADERS " + this.getAllResponseHeaders());
console.log("Connected? " + this.getConnected());
console.log("Type of connection " + this.getConnectionType());
};
Any help or ideas on how to solve this problem would be of great help :D

Related

Bad request error from UrlFetchApp when fetching the API url

I am getting the following error message: Bad request: [URL] when fetching the API URL using UrlFetchApp.
I need to pass the access token which has been received from the authorization server using a GET request.
My code is:-
function run()
{
var service = getOAuthService();
var authorizationUrl = service.getAuthorizationUrl();
Logger.log('Open the following URL and re-run the script: %s',
authorizationUrl);
Logger.log(JSON.stringify(service.getAccessToken(), null, 2));
if (service.hasAccess()) {
var url = 'https://ffa-int-service-lnhtqfum-zgvbwhku.apps.dev.aro.forgeapp.honeywell.com/get_graph_data';
var options =
{
method: 'GET',
headers: {
'Authorization' : 'Bearer ' + service.getAccessToken(),
},
muteHttpExceptions : true,
followRedirects: true
};
var response = UrlFetchApp.fetch(url,options);
var result = JSON.parse(response.getContentText());
Logger.log(JSON.stringify(result, null, 2));
} else {
var authorizationUrl = service.getAuthorizationUrl();
Logger.log('Open the following URL and re-run the script: %s',
authorizationUrl);
}
}

Why do I get this error (failed) net::ERR_CONNECTION_CLOSED after ajax request?

In my localhost it works fine, but on hosting I get this error
(failed) net::ERR_CONNECTION_CLOSED.
What does this error mean and how can I solve this problem? This is a Laravel/vue project.
Code of ajax request:
var firstHalf = this.menu.slice(0, 21);
var secondHalf = this.menu.slice(21);
var result = [firstHalf,secondHalf];
this.isLoading = true;
for (let i = 0; i < result.length; i++) {
let statusCode = 200;
axios({
method: "post",
url: "/admin/menu/addMenu/",
header: {
"X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content")
},
params: {
menu: result[i],
startDate: this.selectedDate,
order: i + 1
}
}).then(response => {
console.log("ajax")
console.log(response.status);
console.log(response);
if (i+1>= result.length) {
this.message = response.data.message;
this.modalShow = true;
this.isLoading = false;
return;
}
});
}
What I did is the following:
var verifyIdentity = formData.get('verify_identity')
if(verifyIdentity && verifyIdentity.size === 0){
formData.delete('verify_identity')
}
Basically saying, if there is a file type attribute, but it is not filled out (meaning you never actually picked the file to submit), just remove it from form data.
It's a tad different example as I don't see what you're actually submitting, but I noticed the issue on my part was due to the type="file" input fields.

How do I send a base64 image to Microsoft-ocr api?

I'm trying to use Microsoft Azure OCR API service to extract some text from an image.
The image I have for sending to the API service has a "data:image/png; base64, " structure and therefore I can't send it with content-type "application/json".
I tried sending it with content-type "multipart/form-data" or "application/octet-stream", but it also fails...
// this "url" gives me the "data:data:image/png;base64, " code
var sourceImageUrl = document.getElementById("myImage").src;
// Perform the REST API call.
$.ajax({
url: uriBase + "?" + $.param(params),
// Request headers.
beforeSend: function(jqXHR){
jqXHR.setRequestHeader("Content-Type","multipart/form-data");
jqXHR.setRequestHeader("Ocp-Apim-Subscription-Key", subscriptionKey);
},
type: "POST",
// Request body.
data: [sourceImageUrl]
})
.done(function(data) {
// Show formatted JSON on webpage.
$("#responseTextArea").val(JSON.stringify(data, null, 2));
})
.fail(function(jqXHR, textStatus, errorThrown) {
// Display error message.
var errorString = (errorThrown === "") ?
"Error. " : errorThrown + " (" + jqXHR.status + "): ";
errorString += (jqXHR.responseText === "") ? "" :
(jQuery.parseJSON(jqXHR.responseText).message) ?
jQuery.parseJSON(jqXHR.responseText).message :
jQuery.parseJSON(jqXHR.responseText).error.message;
alert(errorString);
});
I am bit confused about how I should be sending the image or if I should do some transformations.
Which content-type should I be using to do a proper request?
Should I change the encoding of the image source? How?
Thank you all!
I finally got it working by adding a makeBlob function that returns a blob out of a base64 code. I also set the content-type to "application/octet-stream".
Final code looks like this:
function makeblob(b64Data, contentType, sliceSize) {
contentType = contentType || '';
sliceSize = sliceSize || 512;
var byteCharacters = atob(b64Data);
var byteArrays = [];
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
var slice = byteCharacters.slice(offset, offset + sliceSize);
var byteNumbers = new Array(slice.length);
for (var i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
var blob = new Blob(byteArrays, { type: contentType });
return blob;
}
function recognizeText() {
imageToSend = image.src;
binDataImage = imageToSend.replace("data:image/png;base64,","");
// Perform the REST API call.
$.ajax({
url: uriBase + "?" + $.param(params),
// Request headers.
beforeSend: function(jqXHR){
jqXHR.setRequestHeader("Content-Type","application/octet-stream");
jqXHR.setRequestHeader("Ocp-Apim-Subscription-Key", subscriptionKey);
},
type: "POST",
// Request body.
data: makeblob(binDataImage, 'image/jpeg'),
cache: false,
processData: false
})
.done(function(data) {
// Show formatted JSON on webpage.
$("#responseTextArea").val(JSON.stringify(data, null, 2));
})
.fail(function(jqXHR, textStatus, errorThrown) {
// Display error message.
var errorString = (errorThrown === "") ?
"Error. " : errorThrown + " (" + jqXHR.status + "): ";
errorString += (jqXHR.responseText === "") ? "" :
(jQuery.parseJSON(jqXHR.responseText).message) ?
jQuery.parseJSON(jqXHR.responseText).message :
jQuery.parseJSON(jqXHR.responseText).error.message;
alert(errorString);
});
};

Retrieving of Restful web service values in android for Titanium

We are using the same restful web service code from serviceutility.js for both android and ios. But the service is getting hit and values are retrieved only in ios. The same code is not working in android and we are getting the following error:
[ERROR] : TiExceptionHandler: (main) [2,821093] - In alloy/controllers/home.js:25,32
[ERROR] : TiExceptionHandler: (main) [0,821093] - Message: Uncaught TypeError: Cannot read property 'status' of null
[ERROR] : TiExceptionHandler: (main) [0,821093] - Source: if ("1" == response.status) alert(response.message); else if ("0"
[ERROR] : V8Exception: Exception occurred at alloy/controllers/home.js:25: Uncaught TypeError: Cannot read property 'status' of null.
Titanium SDK is 5.1.2 GA
exports.login = function(user, cb) {
var response = null;
if (Ti.Network.online) {
var xhr = Ti.Network.createHTTPClient({
timeout : 10000,
validatesSecureCertificate : false
});
xhr.onload = function() {// Onload
var responseTxt = this.responseText == '' ? '{}' : this.responseText;
try {
response = JSON.parse(responseTxt);
cb(response, 'SUCCESS');
} catch(e) {
cb(response, 'ERROR');
}
};
xhr.onerror = function(e) {
if (xhr.status === 0) {
cb(response, 'TIMEDOUT');
} else {
cb(response, 'ERROR');
}
};
url = "https://";
var postData = {
employeeId : user.employeeId,
password : user.password
};
xhr.open('POST', url);
xhr.setTimeout(10000);
xhr.setRequestHeader('employeeId', user.employeeId);
xhr.setRequestHeader('password', user.password);
xhr.send();} else {
cb(response, 'NO_NETWORK');
}};
The below code is for index.js file where the actual retrieval of values happen.
if (Ti.Network.online) {
loginUtil.login(user, function(response, status) {
Ti.API.info("status----" + status);
if (response.status == "0") {
Ti.API.info("status== " + response.status);
Ti.App.role = response.role;
Alloy.createController('home', {employeeId:$.userTextField.value,password:$.passwordTextField.value,from:"index"}).getView().open();
} else if (response.status == '1') {
alert(response.message);
} else {
alert("Please enter the correct credentials");
}
});
}
Please help us on this.
Looks like you are ONLY returning a string value instead of the entire response object. Then in your controller you attempt to access the .status property of the response object.
//this line returns the string responseTxt
response = JSON.parse(responseTxt);
Try returning the entire response object instead.
response = JSON.parse(this);
Then in your index.js controller use/ display the status property
alert(response.status);
Your index.js expected response to be an object, but that is only the case where you call callback like this:
response = JSON.parse(responseTxt);
cb(response, 'SUCCESS');
All other places where you call callback the response variable is null, since that is what you initialise it with on the second line.
Your callback returns two parameters, response & status, the second param is never used.
From reading the login function code, you only get to access the response object if status == "SUCCESS"
if(status === "SUCCESS"){
if (response.status == "0") {
Ti.API.info("status== " + response.status);
Ti.App.role = response.role;
Alloy.createController('home', {employeeId:$.userTextField.value,password:$.passwordTextField.value,from:"index"}).getView().open();
} else if (response.status == '1') {
alert(response.message);
} else {
alert("Please enter the correct credentials");
}
}
else {
alert("whoops, please try again !"); // a more generic message.
}

AJAX POST request on IE fails with error "No Transport"?

I'm trying to make an AJAX request to a public service
Here's the code:
$.ajax({
url : "http://api.geonames.org/citiesJSON",
type : 'POST',
cache : false,
dataType : 'json',
data : {
username: "demo",
north:10,
south: 10,
east:10,
west:10}
}).done(function(data) {
alert("Success: " + JSON.stringify(data));
}).fail(function(a, b, c, d) {
alert("Failure: "
+ JSON.stringify(a) + " "
+ JSON.stringify(b) + " "
+ JSON.stringify(c) + " "
+ JSON.stringify(d) );
});
You may try it in this link: http://jsfiddle.net/hDXq3/
The response is retrieved successfully on Chrome & Firefox, and the output is as follows:
But for IE, the fails alerting:
Failure: {"readyState":0,"status":0,"statusText":"No Transport"} "error" "No Transport" undefined
Why it's not working on IE ? and how to fix this ?
Here's the solution for those who are interested:
if (!jQuery.support.cors && window.XDomainRequest) {
var httpRegEx = /^https?:\/\//i;
var getOrPostRegEx = /^get|post$/i;
var sameSchemeRegEx = new RegExp('^'+location.protocol, 'i');
var xmlRegEx = /\/xml/i;
// ajaxTransport exists in jQuery 1.5+
jQuery.ajaxTransport('text html xml json', function(options, userOptions, jqXHR){
// XDomainRequests must be: asynchronous, GET or POST methods, HTTP or HTTPS protocol, and same scheme as calling page
if (options.crossDomain && options.async && getOrPostRegEx.test(options.type) && httpRegEx.test(userOptions.url) && sameSchemeRegEx.test(userOptions.url)) {
var xdr = null;
var userType = (userOptions.dataType||'').toLowerCase();
return {
send: function(headers, complete){
xdr = new XDomainRequest();
if (/^\d+$/.test(userOptions.timeout)) {
xdr.timeout = userOptions.timeout;
}
xdr.ontimeout = function(){
complete(500, 'timeout');
};
xdr.onload = function(){
var allResponseHeaders = 'Content-Length: ' + xdr.responseText.length + '\r\nContent-Type: ' + xdr.contentType;
var status = {
code: 200,
message: 'success'
};
var responses = {
text: xdr.responseText
};
try {
if (userType === 'json') {
try {
responses.json = JSON.parse(xdr.responseText);
} catch(e) {
status.code = 500;
status.message = 'parseerror';
//throw 'Invalid JSON: ' + xdr.responseText;
}
} else if ((userType === 'xml') || ((userType !== 'text') && xmlRegEx.test(xdr.contentType))) {
var doc = new ActiveXObject('Microsoft.XMLDOM');
doc.async = false;
try {
doc.loadXML(xdr.responseText);
} catch(e) {
doc = undefined;
}
if (!doc || !doc.documentElement || doc.getElementsByTagName('parsererror').length) {
status.code = 500;
status.message = 'parseerror';
throw 'Invalid XML: ' + xdr.responseText;
}
responses.xml = doc;
}
} catch(parseMessage) {
throw parseMessage;
} finally {
complete(status.code, status.message, responses, allResponseHeaders);
}
};
xdr.onerror = function(){
complete(500, 'error', {
text: xdr.responseText
});
};
xdr.open(options.type, options.url);
//xdr.send(userOptions.data);
xdr.send();
},
abort: function(){
if (xdr) {
xdr.abort();
}
}
};
}
});
};
jQuery.support.cors = true;
$.ajax({
url : "http://api.geonames.org/citiesJSON",
crossDomain: true,
type : 'POST',
cache : false,
dataType : 'json',
data : {
username: "demo",
north:10,
south: 10,
east:10,
west:10}
}).done(function(data) {
alert("Success: " + JSON.stringify(data));
}).fail(function(a, b, c, d) {
alert("Failure: "
+ JSON.stringify(a) + " "
+ JSON.stringify(b) + " "
+ JSON.stringify(c) + " "
+ JSON.stringify(d) );
});
You may try it in this link: http://jsfiddle.net/bjW8t/4/
Just include the jQuery ajaxTransport extension that uses XDomainRequest for IE8+.

Resources