Immediate object initialization confusion - javascript

I am working on a js file that makes use of JScroll. The callback for the jsp-scroll-y event is defined in the following function
function initWall() {
//callback from jqueryscrollpane
Scroll_TimeLine_Instance = function (event, scrollPositionY, isAtTop, isAtBottom){
//get more content
if (isAtBottom) {
GetMoreDate(objid, vwrsid, secid, orgid, incflwr, qty, mintlid, maxtlid, successGetTimeLineCallback, failureGetTimeLineCallback);
}
}();
}
Another function is defined that then binds this callback to the jsScroll
function reapplyScroll() {
Utilities.DestroyScrollBar($(_target).closest('.widgetBody'));
Utilities.ApplyScrollBar($(_target).closest('.widgetBody'), false, Scroll_TimeLine_Instance);
}
Utilities.ApplyScrollBar = function (element, showScrollBar, scrollCallback) {
$(element).jScrollPane({
horizontalGutter: 5,
verticalGutter: 5,
'showArrows': false
}).bind('jsp-scroll-y', scrollCallback);
if (!showScrollBar) {
$(element).find('.jspDrag').hide();
}
}
The callback was never called, and I found this was because it was undefined. If I remove the Immediate object initialization (); from after the creation of the function everything works fine.
Can anyone explain this? I don't understand why it was being called immediate anyway, so i assume this is an error on the part of whoever created it, and I have no idea why it would cause this variable to be undefined?

It is undefined because the function (that is immediately called) does not return any value
So it seems indeed that this is a bug of the library..
Either remove the (); at the end, or if you want to call it right there as well just invoke it in the following line
function initWall() {
//callback from jqueryscrollpane
Scroll_TimeLine_Instance = function (event, scrollPositionY, isAtTop, isAtBottom){
//get more content
if (isAtBottom) {
GetMoreDate(objid, vwrsid, secid, orgid, incflwr, qty, mintlid, maxtlid, successGetTimeLineCallback, failureGetTimeLineCallback);
}
}; /// this is assigning the function to our variable
Scroll_TimeLine_Instance (); // this is the invokation
}

Related

JS - Calling function from function not working

I have a function that gets called, and in it, I call another function called:
updatePerson(name)
For some reason it never activates when the function below is called. Everything else in the function works.
function updateName(name) {
$.get('XXX',function (data) {
var results = $.parseJSON(data);
var matchName = String(results.data[0].first_name);
updatePerson(matchName);}
);
};
Has anyone got an idea what I am doing wrong?
If I run alert(matchName) I get Nick as a response.
If I run console.log(updateMap(matchAddress)) I get undefined
It could do with the fact that you're passing a parameter from a callback function. In Javascript, variables inside a Callback are not available outside the callback.
Try setting the value of String(results.data[0].first_name) to a variable declared outside of the updateName function (i.e a global variable) and then call the updatePerson function outside of update name, with the globally declared variable as a parameter. Like so
var globalMatchName = '';
function updateName(name) {
$.get('XXX',function (data) {
var results = $.parseJSON(data);
globalMatchName =String(results.data[0].first_name);
}
);
updatePerson(globalMatchName)
}

Javascript Closure and WebRTC callback issues

I'm running into this problem where I'm creating a closure and stepping through with the debugger, the variable connectingClientId is set correctly within the closure callback (localOfferCreated). When the callback is called by createOffer the connectedClientId is undefined. How could this be the circumstance? Been banging my head against the wall all night on this one.
function publishStream(handShakeInitiator, connectingClientId) {
var localOfferCreated = offerClosure(connectingClientId);
var localIceCandidate = iceClosure(connectingClientId);
peerConnections[connectingClientId] = new RTCPeerConnection(peerConnectionConfig);
peerConnections[connectingClientId].onicecandidate = localIceCandidate;
peerConnections[connectingClientId].addStream(localStream);
if (handShakeInitiator) {
peerConnections[connectingClientId].createOffer(localOfferCreated, createOfferError, offerOptions);
}
}
function offerClosure(id) {
var connectingClientId = id;
function offerCreated(description) {
peerConnections[connectingClientId].setLocalDescription(description, function (connectingClientId) {
webSocket.send(JSON.stringify({
'control': signalConstants.sendToClient,
'cid': connectingClientId,
'sdp': description
}));
}, function () {
console.log('Error setting description.');
});
};
return offerCreated;
}
Note these from the debugger:
connectingClientId is set -
connectingClientId is unset upon call -
What am I missing here?
From RTCPeerConnection.setLocalDescription
successCallback
Is a Function without parameter which will be called
when the description has been successfully set. At this point, one can
send the offer to a remote server that can forward it to a remote
client
You are redefining connectingClientID by having it as an inner function parameter. Remember that a named function argument is an implicit variable declaration, and as what docs said, it'll be undefined as the success callback don't give any parameters. JavaScript functions have access to their outer scope, so your anonymous function does not need this arg to be passed, it can simply refer to it creating a closure.
function offerCreated(description) {
peerConnections[connectingClientId].setLocalDescription(description, function() {
webSocket.send(JSON.stringify({
control: signalConstants.sendToClient,
cid: connectingClientId,
sdp: description
}));
}, function () {
console.log('Error setting description.');
});
};

Can I put a method as the argument in the setInterval function?

Preety straight forward question, though I can't find the answer anywhere
I tried these two ways:
setInterval(function(){object/*or this*/.method()},500)
and
setInterval('object/*or this*/.method()',500)
setInterval in fact expects a method as the first argument, though there is an alternative syntax where the first argument can be a string of code (not recommended by most)
If you're having issues with that code, it may have to do with the scope of 'this'
setInterval(function(){this.method()},500)
In the above code, 'this' will refer to the closure itself, and wouldn't be the same as 'this.method' occurring outside of that closure. For example, the following would work:
function MyClass() {
this.thingy = 'yep this is a thingy'
}
var myClass = new MyClass()
// Will log 'MyClass yep this is a thingy'
setInterval(function() { console.log('MyClass', myClass.thingy) }, 1000)
Whereas the following will not work (presuming instantiating the object and calling foo()):
function MyOtherClass() {
this.thingy = 'also a thingy'
}
// Will log 'MyOtherClass undefined'
MyOtherClass.prototype.foo = function() {
setInterval(function() { console.log('MyOtherClass', this.thingy) }, 1000)
}
The second example will work if we get around using 'this' within the closure (presuming instantiating the object and calling bar()):
MyOtherClass.prototype.bar = function() {
var that = this
setInterval(function() { console.log('MyOtherClass', that.thingy) }, 1000)
}
Also be sure that setInterval is being passed the name of a function:
setInterval(someFunction, 500)
rather than executing a function as an argument
setInterval(someFunction(), 500)
This last line of code is usually a mistake, unless someFunction() returns a function itself ;)
The difference between your 2 ways for passing a function to setInterval is whether you want to pass your function as refrence of just copy of it. Allow me to explain it by example:
-1 Referring(demo):
var obj = {
testMethod: function () {
console.log('function (testMethod): intial output');
}
}
setInterval(function () {
obj.testMethod()
}, 1000);
obj.testMethod = function () {
console.log('function (testMethod): changed output');
}
when you run this code, the result 'll be execution of the modified version of testMethod. Because here you dont copy the function! Instead, you refer to it. So whenever function implementation is changed, the last modified version is executed.
-2 Copying(demo):
var obj = {
testMethod: function () {
console.log('function (testMethod): intial output');
}
}
setInterval(obj.testMethod, 1000);
obj.testMethod = function () {
console.log('function (testMethod): changed output');
}
Here all you do is you are passing a copy of the last defined version of the function testMethod to setInterval. So whatever changes you do to testMethod, the result of setInterval will not be changed.

Javascript function execution order

I am new to javascript and have a quick question. Say i have the following code:
function entryPoint()
{
callFunction(parameter);
}
function callFunction(parameter)
{
... //do something here
var anotherFunction = function () { isRun(true); };
}
My question is that when callFunction(parameter) is called, and the variable anotherFunction is declared, does isRun(true) actually execute during this instantiation? I am thinking it doesnt and the contents of the anotherFunction are only "stored" in the variable to be actually executed line by line when, somewhere down the line, the call anotherFunction() is made. Can anyone please clarify the function confusion?
It seems the confusion is this line of code
var anotherFunction = function () { isRun(true); };
This declares a variable of a function / lambda type. The lambda is declared it is not run. The code inside of it will not execute until you invoke it via the variable
anotherFunction(); // Now it runs
You almost described it perfectly.
anotherFunction just receives a reference to a newly created Function Object (yes, Functions are also Objects in this language) but it does not get executed.
You could execute it by calling
anotherFunction();
for instance.
You can write a simple test like so:
entryPoint();
function entryPoint()
{
alert("In entryPoint");
callFunction();
}
function callFunction()
{
alert("In callFunction");
var anotherFunction = function () { isRun(); };
}
function isRun()
{
alert("In isRun");
}
​
And, the answer is no, isRun() does not get called.

Passing Parameters into a Callback Function

I have a function that listens for a click on the screen and fires a callback. It is part of a Helper object (which is why is preceded by the term Helper in my sample code. That is irrelevant however.
var Helper = {
bodyClickListener: function(fn) {
var window = document.getElementsByTagName('body')[0];
window.click();
CORE.dom.on(window, 'click', function(event) {
CORE.dom.off(window, 'click');
fn(event);
});
}
}
I need to be able to pass a function into this function with a parameter that has been previously set.
function someFunction() {
var popup = document.getElementById('tagResultsPopup');
Helper.bodyClickListener(function(popup) {
return function(event) {
event.stopPropagation();
removePopup(popup);
};
}(document.getElementById('tagResultsPopup')));
function removePopup(element) {
if(element) {
element.parentNode.removeChild(element);
}
};
}
The code above works, but you'll notice that I have to set the popup variable inside of the callback function. It has already been set above. How do I pass a reference to the earlier variable into the callback function.
If I understand your question correctly, you don't need to do much. You can just use the popup variable defined outside.
var popup = document.getElementById('tagResultsPopup');
Helper.bodyClickListener(function(event) {
event.stopPropagation();
//Don't set it
//var popup = document.getElementById('tagResultsPopup');
removePopup(popup);//popup will refer to the correct variable
});
The function that you are passing to bodyClickListener is a closure. You can simply reference 'popup' inside that function without any problem. You don't have to create a new variable.
The answer was to use closure in this way:
Helper.bodyClickListener(function(popup) {
return function(event) {
event.stopPropagation();
removePopup(popup);
};
}(document.getElementById('tagResultsPopup')));
That way the callback function has access to the variable I pass into the parameter function. So here, the return is actually the function I am passing as the callback.

Categories