I want user to wait for specified time(4seconds) to get connected to server. If it cannot connect within the specified time period, application should get closed.
Here is what I have coded:
var downloadDataReq = Titanium.Network.createHTTPClient({timeout :4000});
downloadDataReq.onload = function() { //some code }
downloadDataReq.onerror = function(event) { //some code }
var urlToDownloadData = 'http://www.google.com';
downloadDataReq.open("POST", urlToDownloadData);
downloadDataReq.send();
The Problem is that app waits for fix time (timeout parameter does not effect at all).
P.S.: making an app for android using Titanium.
Try to use method like this:
downloadDataReq.setTimeout(4000);
For me, timeout on HTTP requests aren't working as it should. I had very weird issues, such as:
If I put 1000ms timeout, it'll be called on 2 or 3 seconds.
If I put 2000ms timeout or above, it'll never be called.
I'm using Android ICS and JB, and on both I get the issues above. Seems that timeout parameter is buggy.
As a workaround, I'm doing checks inside onload (example: if I'm downloading a file, I compare the checksum of local file, with the checksum of the same file on the server), and I'm simulating timeouts with JavaScript's setTimeout. It's working to an extend.
The code below demonstrate how to simulate a request timeout, with JS's setTimeout command:
var downloadDataReq = Titanium.Network.createHTTPClient();
downloadDataReq.onload = function() {
clearTimeout(timeout);
alert('loaded');
}
downloadDataReq.onerror = function(e) {
clearTimeout(timeout);
alert('error: ' + e.error);
}
var urlToDownloadData = 'http://10.1.1.183/maquina_local/arquivos/FirefoxPortable_12.0_PortugueseBR.paf.exe';
downloadDataReq.open("GET", urlToDownloadData);
var timeout = setTimeout(function(){
downloadDataReq.onload = function(){
downloadDataReq.onerror({'error': 'timeout'});
};
downloadDataReq.abort();
}, 4000);
downloadDataReq.send();
On timeout, I'm changing onload event to onerror one, because if you try aborting a running request, it'll trigger 'onload' event, not 'onerror'. If you don't do it, this issue can give you corrupted files (ex: a 20mb file that, when request is aborted, file will be incomplete, with a size smaller than 20mb).
I'm still testing this solution, but at least for now, it solved a few bugs for me.
Try this.
Ti.App.timeOut = 99000; //declare in app.js
then use anyWhere in your project.But make Sure every time when you create a httpClient.
dont recreate or redefine in Code or through out the page.
this works fine for me.
//HAVE A LOOK OVER THE USE OF THIS
var xhr = Titanium.Network.createHTTPClient({timeout:Ti.App.timeOut});
Related
I have a Nativescript-Vue project built with vue init nativescript-vue/vue-cli-template using the axios library.
If I run the following snippet in a browser environment, it works fine, that is, times out as expected with such a short timeout setting:
const apiClient = axios.create({
timeout: 1,
})
apiClient.request({
url: 'https://jsonplaceholder.typicode.com/todos/1',
}).then(response => {
console.log('this.apiClient.defaults.timeout', apiClient.defaults.timeout)
console.log(response.config)
console.log(response.data)
}).catch(e => {
console.log(e)
})
However, when I run the code in a NativeScript-Vue project on Android, the request completes as if there were no timeout setting present at all. Even though you can see from the console.logs that the value for timeout is 1.
If I make a similar request with NativeScript's "http/http-request" module, the timeout setting is respected as expected.
[Update:]
Turned out that Manoj's workaround below alone wasn't sufficient for our requirements because only connect timeout is set for the HttpURLConnection in org.nativescript.widgets.Async's HttpRequestTask. Setting read timeout provided the desired result, that is, causing the timeout to expire when no data is received within the timeout period. So, I suggested considering setting read timeout in addition to connect timeout:
// apply timeout
if (options.timeout > 0)
{
connection.setConnectTimeout(options.timeout);
connection.setReadTimeout(options.timeout);
}
I guess it's not implemented in the XHR wrapper (as of v6.2.0) but only in the original http request class. Try adding the code below in your app.js.
import { XMLHttpRequest } from 'tns-core-modules/xhr';
import * as types from "tns-core-modules/utils/types";
XMLHttpRequest.prototype.originalSend = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send = function (data) {
if (types.isDefined(this._options) && types.isNumber(this.timeout)) {
this._options.timeout = this.timeout;
}
this.originalSend(data);
};
You might want to submit a issue at Github.
I have a form in which user can add information and add images. The images are base64 encoded so everything is stored in a json object. This object is sent to the server (with $resource) when the user submits it.
If a user adds for example 3 Images with about 2MB per Image, has a shitty connection like Edge, and wants to upload it it seems like it's taking forever. The user just sees the $ionicLoading overlay without information how long it will take or how much % are already uploaded.
The UX is bad because the user could assume, that the app froze or is in an endless loop and that it's just a bad app.
I have the following ideas but no idea if they are possible or
Is there a way in angular, cordova or ionic to get the browserinformation how much % are already uploaded?
Is there a way to get the current uploadspeed? I could get the size of my object by getting the length of my stringified JSON Object, divide it 1024 to get the kB. Then i would check the current uploadSpeed every second and add the current uploadspeed to a variable. With this information i could calculate the uploaded % approximately
JQuery ajaxForm Plugin?
Sounds like what you are looking for is progress events from XHR2.
Assuming your server is setup to handle XHR2 and return content-length, In plain JavaScript:
function upload(blobOrFile) {
var xhr = new XMLHttpRequest();
xhr.open('POST', '/server', true);
xhr.onload = function(e) { ... };
// Listen to the upload progress.
var progressBar = document.querySelector('progress');
xhr.upload.onprogress = function(e) {
if (e.lengthComputable) {
progressBar.value = (e.loaded / e.total) * 100;
progressBar.textContent = progressBar.value; // Fallback for unsupported browsers.
}
};
xhr.send(blobOrFile);
}
upload(new Blob(['hello world'], {type: 'text/plain'}));
Upload speed is also calculable using the information returned in the progress event, as you described.
As for this implementation in AngularJS/Ionic, it seems like this is a longstanding issue within the framework that $http doesn't really support progress events.
I have seen implementations that utilize a special angular directive written for this, or even utilize a jQuery file upload implementation.
I'm using Titanium SDK 3.4.0 GA, developing an Android app that load remote images from my web server to an ImageView.
The problem comes when the device lost connectivity during the load of that images, so, what I need is a way to catch that error (timeout, 404...) and set an "imageNotAvailable".
I'm using Network Link Conditioner for MacOSX to reproduce that scenario, with low latency, lost of packets...
To prove this I use the following code in my test.js (Alloy Controller) and a simple view with an ImageView with id='imageView' in my test.xml.
Sometimes, throws an exception:
TiDownloadManager: (pool-4-thread-1) [45929,118581] Exception downloading http://...
but not always (remote connection timeout seems infinite), anyway with this exception and without this I can't catch this (probably due to the asynchronous request) nor fires the ERROR event.
function imageNotAvailable(e)
{
Ti.API.info('Error loading image:'+JSON.stringify(e));
$.imageView.image = "/imageNotAvailable.png";
}
function onLoad(e)
{
Ti.API.info('Image Loaded:'+JSON.stringify(e));
}
function setImageAndroid(image)
{
try{
$.imageView.image = 'http://....';
}catch(e){
$.imageView.fireEvent("error");
}
$.imageView.addEventListener("error", imageNotAvailable);
$.imageView.addEventListener("load", onLoad);
}
Excuse my bad English! Thanks!
Have you tried adding your event listeners before setting the imageView's image property?
i can suggest a way around using http request
create a function in some library class which accepts the url that you are supposed to hit
Connection.getImage = function(link){
var xhr = Titanium.Network.createHTTPClient({
onload : function(e) {
var responseResult = this.responseText;
callback(responseResult);
},
// function called when an error occurs, including a timeout
onerror : function(e) {
callback("fail");
// Ti.API.info('IN ERROR ' + e.error);
},
timeout : 5000
});
xhr.open("GET", link);
xhr.send();
};
// ps you will receive a blob in response which you can attach to imageView.blob property , an it would suggest using a default image which will act as placeholder until you get the success response.
While creating an Android app in Appcelerator's Titanium that involves both webView and background calls, I ran into a problem / bug where the cookies were getting corrupted on multiple createHTTPClient calls.
Cookies were originally obtained from the webView:
var webview = Ti.UI.createWebView();
webview.url = 'http://www.example.com';
window.add(webview);
webview.addEventListener('load', function(e) {
cookies = e.source.evalJS("document.cookie");
Titanium.App.Properties.setString('cookies',cookies);
}
window.open({modal:true});
and then later used with a background call:
var loader = Titanium.Network.createHTTPClient();
loader.open("GET",base_url + url);
loader.onload = function() {
// process response
}
loader.setRequestHeader('Cookie',Titanium.App.Properties.getString("cookies"));
loader.send();
The first time the above createHTTPClient chunk of code was called, everything worked, but subsequent runs of the above code would send corrupted cookies. In Google App Engine (gae), printing out the request headers would look like this (broken):
logging.info('Request:\n%s' % self.request)
broken response (only the cookie portion of the request header is shown)
Cookie: auth="eyJfdXNlciI6WzYsMSwiVmRoZEtnYWZRMnNxazFjaVM0U1lKdCIsMTM1NzIyMzcwOSwxMzU3MjIzNzA5XX0\075|1357223709|4f622167f477a8c82cab196af4b0029af1a966d7", auth=eyJfdXNlciI6WzYsMSwiVmRoZEtnYWZRMnNxazFjaVM0U1lKdCIsMTM1NzIyMzcwOSwxMzU3MjIzNzA5XX0\075|1357225569|7a469fab7a38a437649c25620729e07c4607f617
Cookie2: $Version=1
working response
Cookie: auth="eyJfdXNlciI6WzYsMSwiVmRoZEtnYWZRMnNxazFjaVM0U1lKdCIsMTM1NzIyMzcwOSwxMzU3MjIzNzA5XX0\075|1357223709|4f622167f477a8c82cab196af4b0029af1a966d7"
...
I suspect the issue has something to do with unicode characters or something inside createHTTPClient. Two auth= statements are shown in the corrupted cookie.
In summary, when the app first launches, the background Titanium.Network.createHTTPClient call works, and any calls after that appear to send corrupted cookies.
The HTTPClient documentation says "object is intended to be used for a single request," so I assumed everything would reset after multiple calls. But something was different after the first call.
Adding loader.clearCookies(base_url); to the code before setting the cookies seems to fix the issue.
var loader = Titanium.Network.createHTTPClient();
loader.open("GET",base_url + url);
loader.onload = function() {
// process response
}
loader.clearCookies(base_url); // THE FIX.
loader.setRequestHeader('Cookie',Titanium.App.Properties.getString("cookies"));
loader.send();
I am working on a sencha touch application where I need to send request to server after every 1 min. I am using setInterval() & setTimeOut() both works in chrome on desktop but when it comes to iPhone or Android it don't work (they don't get called)
Has anyone used these functions before (successfully) or any other functions to use.
Code used
setInterval(function(){
//server calling method
},10000);
setTimeout(function name,10000);
Function name is function which has code to send request to server.
Thank YOu
Why don't you Sencha's DelayedTask class for the purpose? It will be something like this:
//create the delayed task instance with our callback
var task = Ext.create('Ext.util.DelayedTask', function() {
//server calling method
// The task will be called after each 10000 ms
task.delay(10000);
}, this);
//The function will start after 0 milliseconds - so we want to start instantly at first
task.delay(0);
//to stop the task, just call the cancel method
//task.cancel();
And, I worked with this code with Phonegap and it worked fine.
In iPhone generally NSTimer is used.
NSTimer *timer_main = [NSTimer scheduledTimerWithTimeInterval:(1.0) target:self selector:#selector(yourfunction) userInfo:nil repeats:YES];
This will work in iPhone..