Issue with geolocation timeout callback firing whether response received or not - html

I've implemented a timer for a HTML5 geolocation request as per this post Geolocation feedback while accepting the request
However I'm having an issue where the timer is called regardless of whether the navigator.geolocation.received response is true or not. Perhaps I'm missing something very obvious but I can't see what.
Basically, if I get the geo-location information I run the geo_success_action() function, but in every other case (geo-location failure, timeout on accepting location share, or non-existence of html5 geo-location support in the browser), I want to run the geo_failure_action() function.
However what's happening is that if geo-location is collected, my geo_success_action() function is called, and then when the timer runs out the geo_failure_action() is also called.
I had assumed that within var succeed, the setting of navigator.geolocation.received = true would be passed to my timedout function and therefore if navigator.geolocation.received was true, it wouldn't fire the resulting function.
Any thoughts?
var succeed = function(obj) {
navigator.geolocation.received = true;
if (!navigator.geolocation.timedout) {
geo_success_action( obj, json_url );
}
};
var failed = function(obj) {
navigator.geolocation.received = true;
if (!navigator.geolocation.timedout) {
geo_failure_action( json_url );
} else {
geo_failure_action( json_url );
}
};
var timedout = function() {
navigator.geolocation.timedout = true; // could be used for other callbacks to trace if its timed out or not
if (!navigator.geolocation.received){
geo_failure_action( json_url );
//alert('Timed Out');
} else {
null;
}
}
// Extend geolocation object
if ( navigator.geolocation ) {
navigator.geolocation.retrievePermission = function retrievePermission(succeed,failed,options,timeout) {
this.received = false; // reference for timeout callback
this.timedout = false; // reference for other callbacks
this.getCurrentPosition.apply(this,arguments); // actual request
// Trigger timeout with its function; default timeout offset 5000ms
if ( timeout ) {
setTimeout(timeout.callback,timeout.offset || 5000);
}
}
// New location request with timeout callback
navigator.geolocation.retrievePermission(succeed,failed,{},{
offset: 6000, // miliseconds
callback: timedout
});
// If geo-location not supported at all, do failure action
} else {
geo_failure_action( json_url );
}

I haven't tested, but this should work
var timedout = function() {
navigator.geolocation.timedout = true;
if( navigator.geolocation.received === undefined ) {
navigator.geolocation.received = true;
}
if (!navigator.geolocation.received){
geo_failure_action( json_url );
//alert('Timed Out');
} else {
null;
}
}

Related

Ng-Show is not working properly

$scope.stay = function() {
alert("Inside Keep me In")
$scope.timed = false;
$scope.isLogStatus = true;
}
$scope.displayAlert = function() {
$scope.timed = true;
alert("inside display")
}
function idleTimer() {
var t;
$window.onmousemove = resetTimer; // catches mouse movements
$window.onmousedown = resetTimer; // catches mouse movements
$window.onclick = resetTimer; // catches mouse clicks
$window.onscroll = resetTimer;
//window.reload=$scope.stay(); // catches scrolling
// window.onkeypress = resetTimer; //catches keyboard actions
function logout() {
//Adapt to actual logout script
$scope.displayAlert();
alert('insinde logout');
// delete $window.localStorage.user;
// location.href="/";
}
function reload() {
$window.location = self.location.href; //Reloads the current page
}
function resetTimer() {
alert("timer reset")
clearTimeout(t);
// t = setTimeout(logout, 600000); // time is in milliseconds (1000 is 1 second)
$timeout(function() {
alert("timout triggered");
$scope.displayAlert();
}, 9000); // time is in milliseconds (1000 is 1 second)
}
}
idleTimer();
I am using above html and in default if I keep
$scope.timed=true;
it's working
and when I click logged in I am doing
$scope.timed=false;
and again if time is more than 10 minutes I am doing
$scope.timed=true;
(which is not triggering ng-show)
then show is not working
this is controller what is happening
$scope.stay = function() {
alert("Inside Keep me In")
$scope.timed = false;
$scope.isLogStatus = true;
}
$scope.displayAlert = function() {
$scope.timed = true;
alert("inside display")
}
function idleTimer() {
var t;
window.onmousemove = resetTimer; // catches mouse movements
window.onmousedown = resetTimer; // catches mouse movements
window.onclick = resetTimer; // catches mouse clicks
window.onscroll = resetTimer;
//window.reload=$scope.stay(); // catches scrolling
// window.onkeypress = resetTimer; //catches keyboard actions
function logout() {
//Adapt to actual logout script
$scope.displayAlert();
alert('insinde logout');
// delete $window.localStorage.user;
// location.href="/";
}
function reload() {
window.location = self.location.href; //Reloads the current page
}
function resetTimer() {
// alert("timer reset")
clearTimeout(t);
// t = setTimeout(logout, 600000); // time is in milliseconds (1000 is 1 second)
t = setTimeout(logout, 9000); // time is in milliseconds (1000 is 1 second)
}
}
idleTimer();
// Get the topbar menu
$scope.menu = Menus.getMenu('topbar');
The problem is with the way you are calling logout function. You are calling it via outside the angular framework which means that angular will not run the digest cycle and hence any change in scope will not be reflected to the view.
To verify, you can wrap the code in logout function with $timeout. Please do not forget to add it in the dependencies.
$timeout(function(){
$scope.displayAlert();
});
Ideally, you should use angular wrappers e.g. $window for window and $timeout for setTimeout. By doing so angular, automatically, watches for the change and run digest cycle accordingly.

I need to ping a website with ActionScript or Animate

I had found this code ( I need to ping to an network with flash or actionscript )
Im not sure i understand it or how to use it exactly - I need for this to redirect to another frame if it worked and another if it failed
Is anyone able to help?
var ldr:URLLoader = new URLLoader();
ldr.addEventListener(HTTPStatusEvent.HTTP_STATUS, ldrStatus);
var url:String = "URL-TO-SITE";
var limit:int = 10;
var time_start:Number;
var time_stop:Number;
var times:int;
ping();
function ping():void
{
trace("pinging", url);
times = 0;
doThePing();
}
function doThePing():void
{
time_start = getTimer();
ldr.load(new URLRequest(url));
}
function ldrStatus(evt:*):void
{
if(evt.status == 200)
{
time_stop = getTimer();
trace("got response in", time_stop - time_start, "ms");
}
times++;
if(times < limit) doThePing();
}
Well it is trying to load a website 10 times and check the response. I would get rid of the limit though, it make no sense to try it 10 times in a row.
Don't forget that you will need a crossdomain.xml file on your server to be able to access it from flash.
You will need to add some more things for your purpose:
// add an event listener for a failed call
ldr.addEventListener(IOErrorEvent.IO_ERROR, ldrFailed);
ldr.addEventListener(SecurityErrorEvent.SECURITY_ERROR , ldrSecurityError);
function ldrFailed(evt:*):void
{
// loader failed (no internet connection), try to ping again
doFailedRedirect();
}
function ldrSecurityError(evt:*):void
{
// There is an internet connection but probably something is wrong with your crossdomain.xml
doFailedRedirect();
}
function doRedirect():void
{
// make your redirect here
}
function doFailedRedirect():void
{
// something went wrong, do your failed redirect here
}
Adjust the ldrStatus function:
function ldrStatus(evt:*):void
{
if(evt.status == 200)
{
// server responded with status 200 wich means everything is fine
time_stop = getTimer();
trace("got response in", time_stop - time_start, "ms");
doRedirect();
}
else
{
// there is an internet connection but the server returns something else (probably something is wrong with the server)
doFailedRedirect();
}
}

IndexedDB transaction always throwing onabort from add() method in Chrome

I just started experimenting with IndexedDB. I copied an example and pared it down to a small HTML page: Push a button; add a record; dump all the records to the console after the transaction completes.
It runs fine in IE11, but not on Chrome.
The request=transaction.objectstore("store").add({k:v})is always executing the request.onsuccess() method, but the transaction is always resolved with transaction.onabort() by Chrome. Same with .put().
This is the code:
<!DOCTYPE html>
<html>
<head>
<script>
//--- globals
var db;
// The initialization of our stuff in body.onload()
function init() {
var dbVersion = 1;
//--- Try to delete any existing database
var delRequest = indexedDB.deleteDatabase("notesDB");
delRequest.onsuccess = function (de) {
dbOpen(); // .... then open a new one
};
delRequest.onerror = function (de) {
dbOpen(); // ... or open a new one if one doesn't exist to delete
};
function dbOpen () {
var openRequest = indexedDB.open("notesDB", dbVersion);
openRequest.onupgradeneeded = function (e) {
var ldb = e.target.result;
console.log("running onupgradeneeded; always start with a fresh object store");
if (ldb.objectStoreNames.contains("note")) {
ldb.deleteObjectStore("note");
}
if (!ldb.objectStoreNames.contains("note")) {
console.log("creating new note data store");
var objectStore = ldb.createObjectStore("note", { autoIncrement: true });
objectStore.createIndex("title", "title", { unique: false });
}
};
openRequest.onsuccess = function (e) {
db = e.target.result;
db.onerror = function (event) {
// Generic error handler for all errors targeted at this database
alert("Database error: " + event.target.errorCode);
console.dir(event.target);
};
console.log("Database opened; dump existing rows (shouldn't be any)");
displayNotes();
};
openRequest.onerror = function (e) {
console.log("Open error");
console.log(e);
console.dir(e);
};
}
function displayNotes() {
console.log("TODO - print something nice on the page");
var tx = db.transaction("note", "readonly");
tx.oncomplete = function (event) { console.log("read only cursor transaction complete"); }
tx.onerror = function (event) { console.log("readonly transaction onerror"); }
tx.onabort = function (event) { console.log("readonly transaction onabort"); }
// --- iterate cursor
console.log("---Start cursor dump---")
var ds = tx.objectStore("note");
ds.openCursor().onsuccess = function (event) {
var cursor = event.target.result;
if (cursor) {
console.log(cursor.key);
console.dir(cursor.value);
cursor.continue();
}
else {
console.log("---End cursor dump---");
}
};
}
document.querySelector("#test").addEventListener("click", function (clickevent) {
try {
var transaction = db.transaction("note", "readwrite");
transaction.oncomplete = function (event) {
console.log("Cursor dump in 'add' read/write transaction oncomplete");
displayNotes();
console.log("add transaction oncomplete done!");
};
transaction.onerror = function (event) {
console.log("add transaction onerror");
};
transaction.onabort = function (event) {
console.log("add transaction onabort");
};
var objectStore = transaction.objectStore("note");
var request = objectStore.add({
title: "note header",
body: "this is random note body content " + Math.floor(Math.random() * 1000)
});
request.onsuccess = function (event) {
console.log("add request onsuccess");
};
request.onerror = function (event) {
console.log("add request onerror");
console.dir(event);
};
}
catch (e) {
console.log('catchall exception');
console.log(e);
alert("bad things done");
}
});
}
</script>
</head>
<body onload="init()">
<h1>IndexedDB simplest example</h1>
<p>
<button id="test">Push To Add Row To IndexedDB</button>
</p>
</body>
</html>
I clicked the button a bunch of times and it worked every time.
What error are you getting when it aborts? Look in event.target.error in the onabort handler to see. It could be a QuotaExceededError, which would mean that either you have very low hard drive space or you have a lot of data stored in Chrome for your domain. If that's the case, it's good you're running into it now, because you do need to gracefully handle this case, otherwise users will hit it and be confused.

How do I use this URLRequest script?

I started learning ActionScript 3 a week ago and have stumbled across a huge learning curve. I found this script on the internet:
var _loader:URLLoader;
var _request:URLRequest;
function loadData():void {
_loader = new URLLoader();
_request = new URLRequest("http://www.travoid.com/game/Purchase.php?gid=1");
_request.method = URLRequestMethod.POST;
_loader.addEventListener(Event.COMPLETE, onLoadData);
_loader.addEventListener(IOErrorEvent.IO_ERROR, onDataFailedToLoad);
_loader.addEventListener(IOErrorEvent.NETWORK_ERROR, onDataFailedToLoad);
_loader.addEventListener(IOErrorEvent.VERIFY_ERROR, onDataFailedToLoad);
_loader.addEventListener(IOErrorEvent.DISK_ERROR, onDataFailedToLoad);
_loader.load(_request);
}
function onLoadData(e:Event):void {
trace("onLoadData",e.target.data);
}
function onDataFailedToLoad(e:IOErrorEvent):void {
trace("onDataFailedToLoad:",e.text);
}
This all seems to work and is generating no errors or output, however my issue comes about when I use this next part of code (which I made)
function vpBuy(e:MouseEvent):void{
loadData();
if (e.target.data == "false") {
inf_a.visible = true;
inf_b.visible = true;
inf_c.visible = true;
inf_d.visible = true;
btn_ok.visible = true;
}
}
I get this error:
ReferenceError: Error #1069: Property data not found on
flash.display.SimpleButton and there is no default value. at
travoid_fla::MainTimeline/vpBuy() onLoadData
The part that is probably throwing this is:
if (e.target.data == "false") {
I was hoping e.target.data was what stored the value on the web page (which displays as false) but apparently not. With the code I found on the internet, what stores the information on the web page?
Thanks,
Ethan Webster.
The URLLoader load method is asynchronous, you have to wait the server response before triyng to get the result.
The functions onLoadData and onDataFailedToLoad are there to do that. When the response is well received the function onLoadData is called and you can get the data in e.target.data or _loader.data
The error in your function vpBuy is you try to access the data property on the object that triggered the MouseEvent (maybe a Button) and that object don't have such variable.
Try the following:
/** button clicked load the datas from the server **/
function vpBuy(e:MouseEvent):void
{
// load the datas from the server
loadData();
}
/** the datas are well loaded i can access them **/
function onLoadData(e:Event):void
{
trace("onLoadData",e.target.data);
if( e.target.data == "false" )
{
inf_a.visible = true;
inf_b.visible = true;
inf_c.visible = true;
inf_d.visible = true;
btn_ok.visible = true;
}
}
Hope this could help you :)

Parallel form submit and ajax call

I have a web page that invokes long request on the server. The request generates an excel file and stream it back to the client when it is ready.
The request is invoked by creating form element using jQuery and invoking the submit method.
I would like during the request is being processed to display the user with progress of the task.
I thought to do it using jQuery ajax call to service I have on the server that returns status messages.
My problem is that when I am calling this service (using $.ajax) The callback is being called only when the request intiated by the form submit ended.
Any suggestions ?
The code:
<script>
function dummyFunction(){
var notificationContextId = "someid";
var url = $fdbUI.config.baseUrl() + "/Promis/GenerateExcel.aspx";
var $form = $('<form action="' + url + '" method="POST" target="_blank"></form>');
var $hidden = $("<input type='hidden' name='viewModel'/>");
$hidden.val(self.toJSON());
$hidden.appendTo($form);
var $contextId = new $("<input type='hidden' name='notifyContextId'/>").val(notificationContextId);
$contextId.appendTo($form);
$('body').append($form);
self.progressMessages([]);
$fdbUI.notificationHelper.getNotifications(notificationContextId, function (message) {
var messageText = '';
if (message.IsEnded) {
messageText = "Excel is ready to download";
} else if (message.IsError) {
messageText = "An error occured while preparing excel file. Please try again...";
} else {
messageText = message.NotifyData;
}
self.progressMessages.push(messageText);
});
$form.submit();
}
<script>
The code is using utility library that invokes the $.ajax. Its code is:
(function () {
if (!window.flowdbUI) {
throw ("missing reference to flowdb.ui.core.");
}
function NotificationHelper() {
var self = this;
this.intervalId = null;
this.getNotifications = function (contextId, fnCallback) {
if ($.isFunction(fnCallback) == false)
return;
self.intervalId = setInterval(function() {
self._startNotificationPolling(contextId, fnCallback);
}, 500);
};
this._startNotificationPolling = function (contextId, fnCallback) {
if (self._processing)
return;
self._processing = true;
self._notificationPolling(contextId, function (result) {
if (result.success) {
var message = result.retVal;
if (message == null)
return;
if (message.IsEnded || message.IsError) {
clearInterval(self.intervalId);
}
fnCallback(message);
} else {
clearInterval(self.intervalId);
fnCallback({NotifyData:null, IsEnded:false, IsError:true});
}
self._processing = false;
});
};
this._notificationPolling = function (contextId, fnCallback) {
$fdbUI.core.executeAjax("NotificationProvider", { id: contextId }, function(result) {
fnCallback(result);
});
};
return this;
}
window.flowdbUI.notificationHelper = new NotificationHelper();
})();
By default, ASP.NET will only allow a single concurrent request per session, to avoid race conditions. So the server is not responding to your status requests until after the long-polling request is complete.
One possible approach would be to make your form post return immediately, and when the status request shows completion, start up a new request to get the data that it knows is waiting for it on the server.
Or you could try changing the EnableSessionState settings to allow multiple concurrent requests, as described here.