Why does this (javascript) closure fail? - closures

The variable "called" is false when is should be set to true.. why is that?
It is set to true when called by the plugin but outside the closure it remains false.
Its a bit baffling. Thanks in advance for any pointers.
(function() {
module("when InitializedApplication() is called");
test("it should call the success function", function () {
// arrange
$("#qunit-fixture").append(
'<script id="events-catalog-view-template"' +
' type="text/html"'+
' src="_events-catalog.view.html">' +
'</script>' +
'<div id="events-catalog-view-container"' +
' data-bind="template: {' +
' name="events-catalog-view-template" ' +
' afterRender="tpw.mediator.eventscatalog.setupViewDataBinding" ' +
' }"' +
'</div>'
);
var called = false;
// act
var init = TPW.InitializeApplication();
init({
logLevel: "debug",
success: function (successfullResolution) {
called = true;
},
error: function (failedResolution) {
}
});
// assert
ok(called, "success function called");
});
})();

The qunit ok() function was being called before the success callback. Async problem.

Related

RxJS Observable reset timeout

Is it possible to reset/increase the timeout of an Observable after another timeout has already been set? In the following example the timeout of 5 should be overriden with a timeout of 9999, but this does not work:
var source = Rx.Observable
.return(42)
.delay(1000)
.timeout(5)
.timeout(9999); // this statement should override the previous set timeout of 5 MS, but actually it does not
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
Are there any possibilities to override the already set timeout?
Short answer: As far as I know, there is no "legit" solution to this.
Hacky answer: You could connect to the source of the timeout-ed stream and set your own timeout, see the example below how this could be done.
However, I would not advise you to do that in any seriouse project - I'm sure there should be another solution to your problem.
var base = Rx.Observable
.return(42)
.delay(1000)
.timeout(1);
var patched = base.source.timeout(2000);
var subscription = patched.subscribe(
function (x) {
console.log('Patched Next: ' + x);
},
function (err) {
console.log('Patched Error: ' + err);
},
function () {
console.log('Patched Completed');
});
var subscription = base.subscribe(
function (x) {
console.log('Base Next: ' + x);
},
function (err) {
console.log('Base Error: ' + err);
},
function () {
console.log('Base Completed');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.1.0/rx.all.js"></script>
What about if you use a subject to represent your timeout value?
timeoutSubject = new Rx.ReplaySubject(1);
timeoutSubject
.asObservable()
.switchMap((v) => source.timeout(v))
.subscribe((r) => console.log(r));
timeoutSubject.next(5);
timeoutSubject.next(9999);
switchMap should take handle of the unsubscribing/resubscribing for each one of the timeout values.

How can I get the result of geolocation

navigator.geolocation.getCurrentPosition requires three parameters success, fail and options.
What I want to get is the result of position. I have try return the position by success function, but it returns 'undefined'
function success(pos) {
var crd = pos.coords;
console.log('Your current position is:');
console.log('Latitude : ' + crd.latitude);
console.log('Longitude: ' + crd.longitude);
console.log('More or less ' + crd.accuracy + ' meters.');
return pos;
};
pos = navigator.geolocation.getCurrentPosition(success, error, options);
console.log('pos', pos);
The getCurrentPosition returns the Position object back in the success handler
https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/getCurrentPosition
if you wanted to refer to position later on the only way would be storing it in a global variable and using it later. Just remember the global will not be initialised until after the success callback.
var g_pos;
function error(e){
alert(e);
}
function success(pos) {
var crd = pos.coords;
g_pos = pos; // assign to global
console.log('Your current position is:');
console.log('Latitude : ' + crd.latitude);
console.log('Longitude: ' + crd.longitude);
console.log('More or less ' + crd.accuracy + ' meters.');
return pos;
};
var options = {
enableHighAccuracy: true,
timeout: 5000,
maximumAge: 0
};
navigator.geolocation.getCurrentPosition(success, error, options);
//hint type g_pos in console after and you can see the position object.

Remove event handler from memory (ortc) , titanium

I have a memory leak:
var ortc = require("co.realtime.ortc");
function ortcNot() {
ortc.clusterUrl = 'http://ortc-developers.realtime.co/server/2.2';
ortc.connectionMetadata = 'Titanium Example';
ortc.addEventListener('onException', function(e) {
Ti.API.info('Exception: ' + e.info);
});
ortc.addEventListener('onConnected', function(e) {
Ti.API.info('Connected to ORTC server');
ortc.subscribe('yellow24', true);
});
ortc.addEventListener('onDisconnected', function(e) {
Ti.API.info('Disconnected from ORTC');
//remove event handlers
//ortc = null;
});
ortc.addEventListener('onSubscribed', function(e) {
Ti.API.info('Subscribed to: ' + e.channel);
Ti.API.info('Sending a message to: ' + e.channel);
//ortc.send(e.channel, 'Message from iPhone');
});
ortc.addEventListener('onUnsubscribed', function(e) {
Ti.API.info('Unsubscribed from: ' + e.channel);
ortc.disconnect();
});
ortc.addEventListener('onMessage', function(e) {
Ti.API.info('Message received: ' + e.message + ' at channel: ' + e.channel);
//parse message
var message = JSON.parse(e.message);
alert(message.user.message);
//check chat id
if (message.id == args.chatId) {
recieveMessage(message);
}
//ortc.unsubscribe(e.channel);
Ti.API.info(ortc.isConnected());
});
ortc.connect('yellow2');
}
ortcNot();
When I close my controller window, then reopen the window. The old event listeners are still in memory, causing duplicate event listeners to be created.
Any idea why this is happening,and how to solve it? Thanks
Instead of defining listeners with an in-built function, always declare them to a calling function.
To remove an eventListener it has to be identical in both addEventListener and removeEventListener, declaring it as a function and assigning this to the eventListener gets around this. e.g.
var viewObject = null;
function eventTodo(){
// do stuff here ...
viewObject.removeEventListener('click', eventTodo);
}
function addListener() {
viewObject = Ti.UI.createView();
viewObject.addEventListener('click', eventTodo);
 return viewObject;
}
When you close the window you are not calling the removeEventLister which is why every time the window is opened the events are being duplicated. Attach an close event to the window object in question that calls a function to remove all the eventListeners thus removing them from the applications memory.

on() doesn't work with live data using jQuery, how to?

i have some dynamic data that gets appended to a list and any links in that data doesnt seem to work.
i am using jquery 1.8.3 and on() should account for the live method, i think
setInterval(function () {
getNot();
}, 2000);
function getNot() {
var data = {
t1: 'test1',
t2: 'test2',
t3: 'test3'
};
var size = 0,
li = '';
$.each(data, function (k, v) {
li += '<li>' +
'<a href="#" class="add" data-listid="' + k + '">' +
'<h2>load data - ' + k + '</h2>' +
'</a>' +
'</li>';
size++;
});
var but = $('#not'),
ul = $('#not_ul');
but.find('span').text(size + ' Notifications');
ul.html(li);
ul.listview().listview("refresh");
}
// this doesn't seem to work
$('.add').on("click", function () {
var listId = $(this).data('listid');
console.log(listId);
return false;
});
see full example here
any ideas on this issue?
$('.add').on("click", function () {
You need to pass a selector to make on generate a delegate event:
$('#{containerId}').on("click", '.add', function () {
var listId = $(this).data('listid');
console.log(listId);
return false;
});
containerId should be the closest static element to the dynamic created .adds elements.

Send gps coordinates to server every minute

I'm tyring to build a PhoneGap app with jQueryMobile. In my app I need to send a users current geolocations GPS coordinates to server every 4 minute. How can I do this?
This is the code I have been using right now, but it doesn't send any data. How can i modify this to make it work?
document.addEventListener("deviceready", onDeviceReady, false);
var watchID = null;
// PhoneGap is ready
//
function onDeviceReady() {
// Update every 4 minute
var options = { maximumAge: 240000, timeout: 5000, enableHighAccuracy: true };
watchID = navigator.geolocation.watchPosition(onSuccess, onError, options);
}
// onSuccess Geolocation
//
function onSuccess(position) {
var lat = Position.coords.latitude;
var lng = Position.coords.longitude;
jQuery.ajax({
type: "POST",
url: serviceURL+"locationUpdate.php",
data: 'x='+lng+'&y='+lat,
cache: false
});
}
// onError Callback receives a PositionError object
//
function onError(error) {
alert('code: ' + error.code + '\n' +
'message: ' + error.message + '\n');
}
Instead of calling setInterval, let phonegap do that for you.
// onSuccess Callback
// This method accepts a `Position` object, which contains the current GPS coordinates
//
function onSuccess(position) {
var element = document.getElementById('geolocation');
element.innerHTML = 'Latitude: ' + position.coords.latitude + '<br />' +
'Longitude: ' + position.coords.longitude + '<br />' +
'<hr />' + element.innerHTML;
}
// onError Callback receives a PositionError object
//
function onError(error) {
alert('code: ' + error.code + '\n' +
'message: ' + error.message + '\n');
}
// Options: retrieve the location every 3 seconds
//
var watchID = navigator.geolocation.watchPosition(onSuccess, onError, { frequency: 3000 });
http://docs.phonegap.com/en/1.0.0/phonegap_geolocation_geolocation.md.html#geolocation.watchPosition

Resources