JS - Calling function from function not working - javascript

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)
}

Related

How to make JS function wait for JSON data to load?

This works:
function getDataJSON() {
var queryString = "https://www.examplesite.com/someJSON.json";
$.getJSON(queryString, function(data) {
doStuffWithData(data)
});
}
function doStuffWithData(JSON) {
// some code that refers to JSON
}
getDataJSON();
But this complains that a variable (JSON) is undefined somewhere in doStuffWithData():
function getDataJSON(callback) {
// Gets share data and runs callback when received
var queryString = "https://www.examplesite.com/someJSON.json";
$.getJSON(queryString, function(data) {
if(typeof callback === "function") {
callback(data);
}
});
}
function doStuffWithData(JSON) {
// some code that refers to JSON
}
getDataJSON(doStuffWithData());
What am I likely to be doing wrong? The $.getJSON() call takes a second or two so I do need to wait for that and do stuff after it. I think the issue is with the code execution order, but it could be that I've misunderstood how to properly pass the data to the callback function.
It would be better if I could just load the data into a variable all my other functions can access.
This:
getDataJSON(doStuffWithData());
should be this:
getDataJSON(doStuffWithData);
Otherwise it invoked that function immediately and attempts to pass the result of the function into getDataJSON
You need to leave out the parenthesis in this call
getDataJSON(doStuffWithData()); should be getDataJSON(doStuffWithData). The reason is that doStuffWithData is the function and doStuffWithData() is the retrun value from the function.

Why does Javascript need an anonymous function to delay execution?

In my application I need to conduct an IP lookup as a prerequisite to proceeding with execution of another function that needs that data. Originally, I called the function as follows:
$(document).ready(function(){
var ipUrl = "myURL?callback=?";
$.getJSON(ipUrl, function(data) {
window.ip = data['ip'];
console.log("inside function" + window.ip);
}).done(printIp());
});
function printIp() {
console.log("function is done " + window.ip);
}
However, this outputs as
function is done undefined
inside function <ip_address>
I.e. the printIp() function is called before the $.getJSON is actually complete.
If however, I wrap the printIp() call within an anonymous function as follows:
$.getJSON(ipUrl, function(data) {
window.ip = data['ip'];
console.log("inside function" + window.ip);
}).done(function() {
printIp();
});
I get:
inside function <ip_address>
function is done <ip_address>
As I would expect. What is going on here? Why do I need to wrap the function call in an anonymous function?
your code says
}).done(printIp());
what this does is calling printIp and using the result of the function call as an argument to the done method.
what you actually want is passing the function as a done handler. use }).done(printIp); to do this instead.
You are executing printIp right away. Try it without the ():
$.getJSON(ipUrl, function(data) {
window.ip = data['ip'];
console.log("inside function" + window.ip);
}).done(printIp);
pass the function without parantheses, otherwise you are calling it right away:
.done(printIp)

Reassign variables stored in closure using a callback or global function

EDIT
Let me get more to the point. I'm trying to create a psuedo promise implementation. The idea here being that I have a callback that won't be executed until an asynchronous call is received. So I'm simply queueing up all the calls to this function until the time at which it's notified that it can be executed. The queue is emptied and any further call to the function is SUPPOSED to execute immediately, but for some reason, the function is still queueing. This is because, for whatever reason, my redefinition of the runner function is not working correctly. The code below was my sleep deprived, frustrated version of every thought that went through my head. Here's the actual code:
function Promise(callback){
var queue = []
, callback = callback
, runner = function(){
queue.push({
context: this,
args: Array.prototype.slice.call(arguments, 0)
});
}
;//var
runner.exec = function(){
for(var i = 0, ilen = queue.length; i < ilen; i++){
var q = queue[i];
callback.apply(q.context, q.args);
}
runner = callback;
};
return runner;
}
test = Promise(function(){
$('<div/>').appendTo('#output').html(Array.prototype.slice.call(arguments,0).toString());
});
test(1,2);
test(3,4);
test.exec();
test(5,6);​
http://jsfiddle.net/a7gaR/
I'm banging my head against the wall with this one. I'm trying to reassign variables in a function from a call outside the function itself (ideally by passing a reassignment function as a callback). In the example I posted on jsfiddle, I made a global function that, in theory, has a reference to the variables contained within its parent function. Upon calling that external function, I expect it to reassign the values that the other function is using. It doesn't seem to work this way.
window.test = function temp() {
var val = 7,
func = function() {
return val;
};
window.change = function() {
window.test.val = 555555;
$('<div>Changing ' + val + ' to ' + window.test.val +
'</div>').appendTo($output);
val = window.test.val;
temp.val = window.test.val;
func = function() {
return 'Why isn\'t this working?';
}
}
return func();
}
var $output = $('#output');
$('<div/>').appendTo($output).html('::' + test() + '::');
window.change();
$('<div/>').appendTo($output).html('::' + test() + '::');
http://jsfiddle.net/YhyMK/
The second time you call test you're creating a new local variable called func and defining a new window.change that closes over that new variable. The changes you made to the original func by calling the original window.change are not relevant in the second call.
Also note that the following line:
window.test.val = 555555;
...does not modify/refer to the val variable in the outer function. window.test.val refers to a property named val on the test object (which happens to be a function), not any local variable.
You are trying to refer to a local variable in a function with the syntax func.varname. That won't work, that's not the way local variables work.
I finally created a function that would perform this operation. The gist for it is here: https://gist.github.com/2586972.
It works like this...
You make a call to Defer passing the callback whose functionality you'd like to delay:
var deferredCB = Defer(function(){ console.log(this,arguments) };
deferredCB will now store all of the arguments you pass allowing them to be executed at some later date:
defferedCB(1);
defferedCB(2);
Now, when you're ready to perform the operation, you simply "execute" deferredCB:
defferedCB.exec();
Which results in:
// window, 1
// window, 2
All future calls to deferredCB will be executed immediately. And now that I'm thinking about it, I'll probably do a rewrite to allow you to reset deferredCB to it's pre-executed state (storing all the arguments again).
The key to making it work was having a wrapper function. Javascript simply won't let you reassign a function while it's being executed.
TADA!!!

Javascript callback - how to return the result?

I am struggling to totally understand callbacks and i am stumbling at the final hurdle.
Within JS I am calling a function which then calls a PHP function using a dojo rpc Json Service. I have stepped through the function in firebug and the PHP is executing and returning me the correct response via the callback but I don’t know how to return the value to the initial JS variable that invoked the JS function? E.g.
JS Function 1
Function one(){
Var test = getPhp(number);
}
function getPhp(number)
{
this.serviceBroker = new dojo.rpc.JsonService(baseUrl + '/index/json-rpc/');
var result = serviceBroker.phpFunc(number);
result.addCallback(
function (response)
{
if (response.result == 'success')
{
return response.description;
//I am trying to pass this value back to the
//var test value in function one
}
}
);
}
Basically i now need to pass response.description back to my var test variable in function one.
Any help is appreciated
This is not possible, since the callback is run asynchronously. This means that the getPhp function returns before the callback is executed (this is the definition of a callback, and one of the reasons asynchronous programming is hard ;-) ).
What you want to do is create a new method that uses the test variable. You need to call this method when the callback is executed.
i.e.
function one(result) {
var test = result;
// Do anything you like
}
function getPhp(number, callback) {
this.serviceBroker = new dojo.rpc.JsonService(baseUrl + '/index/json-rpc/');
result.addCallback(
function (response)
{
if (response.result == 'success')
{
callback(response.description);
}
}
);
}
getPhp(number, function(result) { one(result); });
This last method creates an 'anonymous function' that is passed to the getPhp function. This function gets executed at the time the response arrives. This way you can pass data to the one(number) function after the data arrives.
The short answer is that you can't.
Do whatever you want to do with the data in the callback or functions you call from the callback. You can't return anything from it.
A much cleaner answer:
getPhp(number);
function one(data){
var test = data;
// do what you want
}
function getPhp(number)
{
this.serviceBroker = new dojo.rpc.JsonService(baseUrl + '/index/json-rpc/');
var result = serviceBroker.phpFunc(number);
result.addCallback(
function (response)
{
if (response.result == 'success')
{
one(response.description);
}
}
);
}

Javascript callback functions execution

I'm not sure the correct term for this. But I want to write a function that accepts another function and execute it.
For eg.
function test(data, aFunc) {
var newData = data + " Shawn";
aFunc.call(newData);
}
test("hello", function(data){
alert(data);
});
Data is supposed to contain "hello Shawn" string. Help me rewrite this the correct way please.
The first argument of the call method is used to set the this keyword (the function context) explicitly, inside the invoked function, e.g.:
function test(data, aFunc) {
var newData = data + " Shawn";
aFunc.call(newData);
}
test("hello", function () {
alert(this); // hello Shawn
});
If you want to invoke a function without caring about the context (the this keyword), you can invoke it directly without call:
function test(data, aFunc) {
var newData = data + " Shawn";
aFunc(newData); // or aFunc.call(null, newData);
}
test("hello", function (data) {
alert(data);
});
Note that if you simply invoke a function like aFunc(newData); or you use the call or apply methods with the this argument set as null or undefined, the this keyword inside the invoked function will refer to the Global object (window).
Looks fine but you can just change
aFunc.call(newData);
to
aFunc(newData);
You were close. The first argument to "call" is the "scope" argument. In this case, it doesn't matter what it is, because you're not using "this" anywhere in your anonymous function, so any value will suffice.
function test(data, aFunc) {
var newData = data + " Shawn";
aFunc.call(this, newData);
}
test("hello", function(data){
alert(data);
});

Categories