i am new to JavaScript, i am learning javascript from a book "Visual Quickstart guide",
i am struggling with the following code logic, as function definition shows it expects an argument,
function getNewFile(evt) {
makeRequest(this.href);
evt.preventDefault();
}
but when the function is being called there is not argument being passed to it,
function initAll() {
document.getElementById("makeTextRequest").addEventListener("click",getNewFile,false);
document.getElementById("makeXMLRequest").addEventListener("click",getNewFile,false);
}
i do not understand the default behavour of this function when no arguments have been passed to it,
complete code from the book
window.addEventListener("load",initAll,false);
var xhr = false;
function initAll() {
document.getElementById("makeTextRequest").addEventListener("click",getNewFile,false);
document.getElementById("makeXMLRequest").addEventListener("click",getNewFile,false);
}
function getNewFile(evt) {
makeRequest(this.href);
evt.preventDefault();
}
function makeRequest(url) {
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
}
else {
if (window.ActiveXObject) {
try {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e) {
}
}
}
if (xhr) {
xhr.addEventListener("readystatechange",showContents,false);
xhr.open("GET", url, true);
xhr.send(null);
}
else {
document.getElementById("updateArea").innerHTML = "Sorry, but I couldn't create an XMLHttpRequest";
}
}
function showContents() {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
if (xhr.responseXML && xhr.responseXML.childNodes.length > 0) {
var outMsg = getText(xhr.responseXML.getElementsByTagName("choices")[0]);
}
else {
var outMsg = xhr.responseText;
}
}
else {
var outMsg = "There was a problem with the request " + xhr.status;
}
document.getElementById("updateArea").innerHTML = outMsg;
}
function getText(inVal) {
if (inVal.textContent) {
return inVal.textContent;
}
return inVal.text;
}
}
The below code, the 'getNewFile' method is being passed in as a parameter and isn't actually executed until the 'click' even is raised, then it is executed with the expected parameter arguments.
function initAll() {
document.getElementById("makeTextRequest").addEventListener("click",getNewFile,false);
document.getElementById("makeXMLRequest").addEventListener("click",getNewFile,false);
}
In Javascipt, Functions are objects just as numbers, strings, array, etc. If the function name doesn't have "()" double parenthesis after it (with or without out arguments) then it's not being executed right then, but rather being passed as a parameter for future reference/execution.
Here's a couple simple examples of passing Functions as a parameter:
Example 1
function example1() {
alert('hello');
}
function executor1(f) {
// execute the function passed in through argument 'f'
f();
}
executor(example1);
// example1 isn't executed/called until it's called from within executor1
Example 2
function add(a, b) {
return a + b;
}
function multiply(a, b) {
return a * b;
}
function alertMath(a, b, f) {
var result = f(a, b);
alert(result);
}
// alerts the message of "3"
alertMath(1, 2, add);
// alerts the message of "6"
alertMath(2, 3, multiply);
// alerts the message of "3"
// this shows a function being defined inline
alertMath(6, 2, function(a, b) {
return a / b;
});
I hope this gives you a little more context surrounding this as to what's going on.
In here :
function getNewFile(evt) {
makeRequest(this.href);
evt.preventDefault();
}
getNewFile is the function reference, getNewFile(parameter) is the function call.
As you can see here :
document.getElementById("makeTextRequest").addEventListener("click",getNewFile,false);
getNewFile (function reference, not function call) is passed on to addEventListener. According to the addEventListener documentation, the second parameter is the listener, which is the function that will be called when the event triggers.
Related
I have been working to create a function that given another function will make that second function only callable once. not unlike the _.once() function.
the desired outcome is the following:
const oneTimeFunction = _.once(function(string) { string.split(''); })
oneTimeFunction('hello')
//returns: 'olleh', and if called again it would have no effect returning the same thing a the original call.
Currently this is what I have:
_.once = function (func) {
var called = 0;
let args = null;
if (arguments.length > 1) {
args = Array.prototype.slice.call(arguments,1);
}
return function () {
if (called === 0) {
console.log('being called');
called ++;
if (!args) {
console.log('without apply');
return func.call(arguments);
} else {
console.log('with apply');
return func.apply(this,args);
}
} else {
console.log('this has been called');
return null;
}
};
};
I am running into a wall as it is returning error type undefined even with everything I have tried. Any help, even to get to where it can call the function regardless of the one time only stipulation? Thanks!
create a variable that count how much this function is called
let count = 0;
function once(str) {
if(count < 1){
count++;
return str.split("").reverse().join("");
}
else return str;
}
console.log(once("hello")); // olleh
console.log(once("hello")); // hello
console.log(once("hello")); // hello
In reading your question, I'm seeing that you would like to always return the first value on subsequent calls:
"if called again it would have no effect returning the same thing a[s] the original call."
So I believe you want to do something like this:
function computeOnce(myFn) {
let origVal = undefined;
return function (...args) {
// if this is not set, this is the first call
if (!origVal) {
// execute the function and store it's return value
origVal = myFn(...args);
}
return origVal;
}
}
var ajax = function(url,callback) {
if(window.XMLHttpRequest) {
xml = new XMLHttpRequest();
}
if(window.ActiveXObject) {
var xml = new ActiveXObject("Microsoft.XMLHTTP");
}
this.xml = xml;
alert(xml);
xml.onreadystatechange = function(callback) {
callback = callback();
if(xml.readyState == 4 && xml.status == 200) {
alert(xml);
}
}
xml.open('GET',url,true);
xml.send(null);
}
ajax('/server/eChck.php?email=email#yahoo.com',function(){
alert(xml);
});
the callback() wont work. Produces syntax error. can any explain to me how I would code this so I could put my callback() inside of the parameter?
Thanks,
Jon W
There are two mistakes here:
xml.onreadystatechange = function(callback) {
callback = callback();
if(xml.readyState == 4 && xml.status == 200) {
alert(xml);
}
}
First, you're creating the ready state change handler as a function that takes a parameter, which isn't incorrect but you've named that parameter "callback". That means that inside the state change handler, "callback" refers to that parameter, not to the "callback" passed in to the outer function.
Second, by assigning to "callback" the result of calling the callback function, you'll overwrite the value each time the event handler is called.
I think you want something like this:
xml.onreadystatechange = function() {
if(xml.readyState == 4 && xml.status == 200) {
callback();
}
}
edit — In addition to those changes, you should declare the "xml" variable in your "ajax" function:
var ajax = function(url,callback) {
var xml;
And take out this line:
this.xml = xml; // take this out
function MyFunction () {
if (SomeCondition) {
MyInnerFunction(SomeParam);
return;
}
if (SomeOtherCondition) {
MyInnerFunction(SomeOtherParam);
return;
}
if (SomeThirdCondition) {
MyInnerFunction(AnotherParam);
return;
}
function MyInnerFunction(Param) {
// Do some work here
// HERE: I want return from MyFunction
}
}
As you can see, when MyInnerFunction returns, the next statement to execute is the return statement of MyFunction. Is there a way to eliminate all these return statements so that the return from MyFunction executes inside MyInnerFunction?
Thanks.
you could reformat the code so that your if conditions are only modifying the parameters.
Then you just call your method with the correct parameters at the end
function MyFunction () {
var params;
if (SomeCondition)
params = SomeParam;
else if (SomeOtherCondition)
params = SomeOtherParam;
else if (SomeThirdCondition)
params = AnotherParam;
MyInnerFunction(params);
}
I want to be able to perform some logic within a callback function based on whether callback(true) or callback(false) was called in the preceeding function.
Example:
foo.doFunction = function (param, callback)
{
int a = 1;
int b = param;
if(a < param)
{
callback(false);
}
else
{
callback(true);
}
}
foo.doFunction(param, function()
{
if(true)
{
}
if(false)
{
}
});
Is what I am trying to achieve possible through the use of callbacks?
Thanks for your time.
Yes, though your callback function would need to read the argument by name or using the arguments array:
foo.doFunction(param, function(myParam)
{
if(myParam)
{
}
else
{
}
});
I am trying to use doh.Deferred to write a test that will check the following sequence of events:
login with user A (asynchronous)
log out (synchronous)
login with user A (asynchronous)
The return value of the second callback function is another doh.Deferred object. I was under the impression that the callback chain of d will wait for d2 but it does not. The test finishes before d2.callback is ever called.
Where am I going wrong here?
Does anyone know of a better way for me to test this behavior?
function test() {
var d = new doh.Deferred();
d.addCallback(function() {
Comm.logout(); /* synchronus */
try {
// check with doh.t and doh.is
return true;
} catch (e) {
d.errback(e);
}
});
d.addCallback(function() {
var d2 = new dojo.Deferred();
/* asynchronus - third parameter is a callback */
Comm.login('alex', 'asdf', function(result, msg) {
try {
// check with doh.t and doh.is
d2.callback(true);
} catch (e) {
d2.errback(e);
}
});
return d2; // returning doh.Defferred -- expect d to wait for d2.callback
});
/* asynchronus - third parameter is a callback */
Comm.login('larry', '123', function (result, msg) {
try {
// check with doh.t and doh.is
d.callback(true);
} catch (e) {
d.errback(e);
}
});
return d;
}
This works. The scope of d2 was the problem.
function test() {
var d = new doh.Deferred();
var d2 = new doh.Deferred();
d.addCallback(function() {
Comm.logout(); /* synchronus */
try {
// check with doh.t and doh.is
return true;
} catch (e) {
d.errback(e);
}
});
d.addCallback(function() {
/* asynchronus - third parameter is a callback */
Comm.login('alex', 'asdf', function(result, msg) {
try {
// check with doh.t and doh.is
d2.callback(true);
} catch (e) {
d2.errback(e);
}
});
return d2; // returning doh.Deferred -- waits for d2.callback
});
/* asynchronus - third parameter is a callback */
Comm.login('larry', '123', function (result, msg) {
try {
// check with doh.t and doh.is
d.callback(true);
} catch (e) {
d.errback(e);
}
});
return d;
}