This is an example of how I currently make an api call using titanium:
var url = "http://www.appcelerator.com";
var client = Ti.Network.createHTTPClient({
// function called when the response data is available
onload : function(e) {
Ti.API.info("Received text: " + this.responseText);
alert('success');
},
// function called when an error occurs, including a timeout
onerror : function(e) {
Ti.API.debug(e.error);
alert('error');
},
timeout : 5000 // in milliseconds
});
// Prepare the connection.
client.open("GET", url);
// Send the request.
client.send();
The trouble is by doing it this way, I am only able to access the object in the onload call back function.
I can't for example do this:
//snippet
var someObject;
onerror : function(e) {
someObject = this.responseText;
},
//end
function useObject(someObject){
alert(someObject);
}
Using jquery AJAX I would be able to do this, like this:
$.ajax({
type: "POST",
url: 'someurl',
data: param = "",
contentType: "application/json; charset=utf-8",
success: self.useObject,
error: errorFunc
});
Once the response is received, pass it to the success object.
How can I do the equilent in Titanium, given that it does not use Jquery.
I don't fully understand what you are trying to achieve ,but try something like:
var onLoad = function(e) {
console.log(this.responseText);
};
var client = Ti.Network.createHTTPClient({
onload: onLoad
});
Related
I have developed an ASP.NET MVC Application using JavaScript, jQuery.
I have implemented to be restrict multiple user logins at same time using onbeforeunload/beforeunloadevent.
It works fine, but sometimes not working in onbeforeunload/beforeunloadevent.
var myEvent = window.attachEvent || window.addEventListener;
var chkevent = window.attachEvent ? 'onbeforeunload' : 'beforeunload'; /// make IE7, IE8 compitable
myEvent(chkevent, function (e) { // For >=IE7, Chrome, Firefox
if (!validNavigation)
{
$.ajax({
url: '#Url.Action("ClearSession", "Account")',
type: 'Post',
data: "",
dataType: "json",
success: function (data)
{
console.log("onbeforeunload Success")
},
error: function (data) {
console.log("onbeforeunload Error")
}
});
}
return null;
});
There is one also function in AJAX - jQuery is called complete: function(){};
This function checks weather request is running for same user id and password on browser or not, Like this here
complete: function() {
$(this).data('requestRunning', false);
}
Whole AJAX-jQuery implementation here see and implement accordingly, I hope it will work fine for you
Code Here
$('#do-login').click(function(e) {
var me = $(this);
e.preventDefault();
if ( me.data('requestRunning') ) {
return;
}
me.data('requestRunning', true);
$.ajax({
type: "POST",
url: "/php/auth/login.php",
data: $("#login-form").serialize(),
success: function(msg) {
//stuffs
},
complete: function() {
me.data('requestRunning', false);
}
});
});
See this me.data('requestRunning', false); if it will get any request running for same user id and password it returns false and cancel login.
For more help see here link Duplicate, Ajax prevent multiple request on click
This is not perfect solution but you can implement like this
I've built into an app a File Upload with Progress bar using jQuery.ajax .
But I'm concerned that I don't understand how garbage collection will handle it and therefore how memory efficient it will be.
For the progress bar, I had to add a custom xhr in order to add a "progress" event.
When will that custom xhr function and 'progress' event handler be cleaned up?
myApp.prototype.uploadFile = function () {
$.ajax({
type : "POST",
url : posturl,
xhr : function () { // custom xhr
var myXhr = $.ajaxSettings.xhr();
this.onSaveProgress(myXhr, file);
return myXhr;
}.bind(this),
contentType: false,
processData: false,
data : postdata,
beforeSend : this.onBeforeSend,
success : this.onSaveSuccess,
error : this.onSaveError
});
},
myApp.prototype.onSaveProgress = function (xhr, file) {
if (!xhr.upload)
return;
xhr.upload.addEventListener("progress", function (e) {
if (e.lengthComputable) {
var percent = Math.floor((e.loaded / e.total)*100) + "%";
$("#progress" + file.id).css("width", percent).text(percent);
}
}, false); // add new progress event handler
}
As you can see, I needed access to the file Object in the 'progress' event handler so I can update the correct progress bar.
I know that this question is asked in many ways, I'm also able to make it work. It only doesn't work in combination with a key* event...
Why doesn't .abort() work in this function?
function setGlobalSearch(){
var xhr;
$('#globalSearch').keyup(function(){
if(xhr && xhr.readystate != 4){
xhr.abort();
}
var searchVal = $(this).val();
xhr = $.ajax({
type: "GET",
url: "/ajax.actions?i=globalSearch&q="+searchVal,
success: function(data) {
$('#globalSearchResults').html(data);
},
dataType:"html",
cache:false
});
});
}
The abort() function will only fire if the request has been sent. I can only suggest that this is possibly not the case.
However, I would recommend a different pattern which negates the need to abort requests, which is, as you've seen, occasionally a little flaky. Instead I would only fire the request once typing has ceased for a set number of milliseconds. Try this:
var timer;
$('#globalSearch').keyup(function() {
clearTimeout(timer);
timer = setTimeout(function() {
var searchVal = $(this).val();
$.ajax({
type: "GET",
url: "/ajax.actions?i=globalSearch&q="+searchVal,
success: function(data) {
$('#globalSearchResults').html(data);
},
dataType:"html",
cache:false
});
}, 150); // fire the AJAX request 150ms after typing stops.
});
My code is working fine, but I do not like at all.
I would like to split one file into two files, one containing webServices and another one with a controller.
My file do something like this:
File: Validacion.js (controller)
// Load next view
var MainView = Alloy.createController('index').getView('tabGroup');
// this a function call when I click a button "validar" on ValidaciĆ³n View.
function btnClick(){
var url = 'www.cocoloco.com/whatever';
var webService = Ti.Network.createHTTPClient({
onload: function(e){
// open new view
MainView.open();
// close actual view
$.tabValidacion.close();
$.tabValidacion = null;
},
onerror: function(e){
alert('onerror: ' + e.error);
},
timeout: 5000
});
webService.open('POST', url);
webService.send();
}
But I would like to do something like this below (divided in two files: webServices.js -library- and validation.js -controller-).
The problem is that I always have the message "error" because I pass throught "success = webServices.protocol();" but as far as it is "asynchronous" it doesn't stop and goes to following line of code without having server answer yet.
File: webServices.js (library)
exports.protocol = function(){
var url = 'www.cocoloco.com/whatever';
var webService = Ti.Network.createHTTPClient({
onload: function(e){
// on sucess exit with true
return(true);
},
onerror: function(e){
alert('onerror: ' + e.error);
// on sucess exit with false
return(false);
},
timeout: 5000
});
webService.open('POST', url);
webService.send();
}
File: Validacion.js (controller)
// Load next view
var MainView = Alloy.createController('index').getView('tabGroup');
function btnClick(){
var webServices = require('webServices');
var success = webServices.protocol();
if(success){
// open new view
MainView.open();
// close actual view
$.tabValidacion.close();
$.tabValidacion = null;
}else{
alert('error');
}
}
I have thought about two possible options:
Using promises.
Fire a new event on "success" and use that event run another callback function (in this function I open the new view and close the previous one).
I do not know how difficult is this as far as the event is one file (library) and the callback function in another one (controller)
I have never used any of these solutions, so I do not know how "good" they are.
Any suggestion?
The callback approach works fine in most cases. Just pass the function as a parameter, you can return an object containing anything from a success message to responseText and status.
webServices.js
exports.protocol = function(callback) {
var url = 'www.cocoloco.com/whatever';
var webService = Ti.Network.createHTTPClient({
onload: function(e){
// on success call callback
callback({ success: true });
},
onerror: function(e){
// on error call callback
callback({ success: false });
},
timeout: 5000
});
webService.open('POST', url);
webService.send();
}
Validacion.js
function btnClick(){
var webServices = require('webServices');
webServices.protocol(function(e) {
if(e.success){
// open new view
MainView.open();
// close actual view
$.tabValidacion.close();
$.tabValidacion = null;
} else {
alert('error');
}
});
}
I have a procedure running on a timeout to load data in the background:
(function getSubPage() {
setTimeout(function() {
if (cnt++ < pagelist.length) {
loadSubPage(pagelist[cnt]);
getSubPage();
}
}, 500);
})();
In loadSubPage() I'm making $.ajax() calls:
function loadSubPage(page) {
if (typeof(initSubPages[page]) === "undefined") {
$.ajax({
type: "POST",
url: '/Main/GetPageData',
data: { page: page },
success: function (returndata) {
// ...
},
error: function() {
alert("Error retrieving page data.");
}
});
initSubPages[page] = true;
}
}
The problem I'm having is that the error handler is being hit when the user navigates away if any ajax requests are open. I'm trying to get around this by .stop()ing the requests on window.onbeforeunload, but I'm not sure what object to call .stop() on?
jQuery exposes the XMLHttpRequest object's abort method so you can call it and cancel the request. You would need to store the open request into a variable and call abort().
activeRequest = $.ajax({...
and to stop it
activeRequest.abort()
Abort Ajax requests using jQuery
This should come in handy.. You have a jQuery method for doing just that.
The $.ajax returns XMLHTTPRequestObject which has .abort function. This function will halt the request before it completes.
var xhr = $.ajax({ /*...*/
..
..
/* Later somewhere you want to stop*/
xhr.abort();
Read more: How to cancel/abort jQuery AJAX request?
Here is the solution I used based on the feedback:
window.onbeforeunload = function() {
for (page in ajaxing) {
if (ajaxing[page] != null)
ajaxing[page].abort();
}
};
var ajaxing = {};
function loadSubPage(page) {
if (typeof(initSubPages[page]) === "undefined") {
var ajaxRequest = $.ajax({
type: "POST",
url: '/Main/GetPageData',
data: { page: page },
success: function (returndata) {
// ...
},
error: function() {
alert("Error retrieving page data.");
},
complete: function() {
ajaxing[lot] = null;
}
});
ajaxing[page] = ajaxRequest;
initSubPages[page] = true;
}
}