How to invoke function call if it is defined as var? - javascript

I'm getting data from server using JQuery and JSON. I defined getBooksDoneFunc
as variable because I need to be able to call this function not only once (when getBooks is done) . Unfortunately, I cannot call getBooksDoneFunc from inside of signInOK as window["getBooksDoneFunc"]();. Why? What is the best way to call this function?
function getBooks(){ return $.getJSON( "bookstore.json" ); }
var getBooksDoneFunc = function(json) {
$.each(json.books, function(i, json){ .......... });
}
getBooks().done(getBooksDoneFunc);
function signInOK(){
window["getBooksDoneFunc"]();
}
PS. The idea for window["getBooksDoneFunc"](); was taken from SO answer
UPDATE:
var booksJSON = {};
window["getBooksDoneFunc"](booksJSON);
getBooksDoneFunc must be called with parameters nevertheless the call to getBooksDoneFunc fails. signInOK is defined outside of $(document).ready(function(){ }); but called inside of it.

Try:
function getBooks(){
return $.getJSON( "bookstore.json" );
}
window.getBooksDoneFunc = function(json) {
$.each(json.books, function(i, json){ .......... });
}
getBooks().done(getBooksDoneFunc);
$(document)ready(function() {
function signInOK(){
var booksJSON = {};
window.getBooksDoneFunc(booksJSON);
}
});

If window["getBooksDoneFunc"](); works, then does getBooksDoneFunc(), the idea of using window is when you want to access a global function but you don't know the function name which is stored in a variable.
In your case, put a hardcoding string is mean less, just do getBooksDoneFunc() is the same, because you already store the function self (not the string of function name) in the variable.
The thing that won't work is that if the variable is not global, please check the scope.

I would do this a bit differently, although I do not really understand the signInOK() function. How will it receive the "json" data. I would reconstruct the getBooks function and rethink the signInOk function. Here's a start:
function getBooks() {
$.getJSON("bookstore.json").done(function (json) {
getBooksDoneFunc(json);
});
}
var getBooksDoneFunc = function(json) {
$.each(json.books, function(i, json){ .......... });
};
...
getBooks();
function signInOK(){
getBooksDoneFunc("some json data");
}

Related

Using closure for storing and retrieving data

I am trying to use closure for storing and retrieving variable at the same time.
I am using JSONP and callback to the function
http://freegeoip.net/json/?callback=geoIPInfo
Closure
function geoIPInfo(newGeoData) {
var geoInfo;
if (newGeoData) {
geoInfo = newGeoData;
}
var provideGeoData = function () {
return geoInfo;
};
return provideGeoData();
}
I want firstly to store data and than retrieve last saved data from the closure using simple call like that
geoIPInfo()
If argument provided it will set new info otherwise it will return existing one.
But in my case data is set successfully, but when I try to get set data I get undefined
$("#super_button").click(function (e) {
alert(geoIPInfo());
e.preventDefault();
});
What is wrong with my closure understanding ?
Please explain.
Thank you.
This will work. The idea here is we create a function that returns a function with that accepts a parameter and we store geoInfo in a closure to keep it value. Idk if that makes sense, if you need a better explanation I can give it another try :)
var geoIPInfo = function() {
var geoInfo;
var provideGeoData = function (newGeoData) {
if (newGeoData) {
geoInfo = newGeoData;
}
return geoInfo;
};
return provideGeoData;
}();
Each time you call geoIPInfo(), you're re-declaring the local variable geoInfo. You'll want to declare geoInfo once, and have it accessible to geoIPInfo() via a closure:
//Create a closure
var geoIPInfo = (function(){
//Private variable, available via closure
var geoInfo;
function geoIPInfo(newGeoData) {
if (newGeoData) {
geoInfo = newGeoData;
}
var provideGeoData = function () {
return geoInfo;
};
return provideGeoData();
}
return geoIPInfo;
})();
alert(geoIPInfo()); //undefined
geoIPInfo('Some Data');
alert(geoIPInfo()); //'Some Data'
Here, we're creating a closure using an Immediately-Invoked Function Expression (IIFE).

how to pass function in json as a function?

in arrayRec , onShow value should be a function.
Following is my reference code.
Any help?
This is my reference code:
if (rec.element_flag == '111'){
var arrayRec = [];
$.ajax({
type:'GET',
url: "/aps/one-url",
success: function(responseData){
for (var i = 0; i < responseData.length; i++){
var recJ;
var newFunction1 = function onshowdata(counter){
if(responseData[counter].fields.on_show_fn != null){
return function responseData[counter].fields.on_show_fn;
}
else
return;
}
recJ = {
element: responseData[i].fields.element_class,
placement: responseData[i].fields.placement,
title: responseData[i].fields.title,
content: responseData[i].fields.content,
onShow: newFunction1(i)
}
arrayRec.push(recJ);
console.log('-------arrayRec------');
console.log(arrayRec)
aps.walk.setupBootstrap(arrayRec);
}
},
error: function(){
alert('get failure');
}
});
}
Tried many ways but what I am missing?
in JSON, only text can be used, not objects. Functions are objects too. So, in JSON, name of the function can be passed, not the function object. An alternate way is to send the text of that entire function, which can be run using "eval", though this way is not recommended.
Use closure technique here. Define function above the ajax code, and use the name of the function inside it, which is a standard method of doing this.

How can I pass this specific variable I'm using jquery-ajax

I want to pass the "passedThisValue" to my "start_battle" function and use the "start_battle" function in my "Rematch". But the modal just hangs why is this happening? what could be wrong? Please help! :) Thank you.
CODE:
function start_battle(){
$.ajax({
data: {
receivePassedValue: passedThisValue
},
success: function(data){
}
});
}
$("#start_battle").click(function() {
$.ajax({
success: function(data){
var toAppend = '';
if(typeof data === "object"){
var passedThisValue = '';
for(var i=0;i<data.length;i++){
passedThisValue = data[i]['thisValue'];
}
start_battle(); // can I still get the passedThisValue?
}
}
});
$("#battle").dialog({
modal:true,
buttons: {
"Rematch": function(){
start_battle(); // can I still get the passedThisValue?
}
}
});
$("#battle").show(500);
});
When you call a function, you don't use function start_battle();, you just use start_battle();.
When you pass a value to a function, you need to use this syntax: start_battle(param1, param2);.
When you want to get a value from a function, you need to return it in the function, like so:
function start_battle(param1) {
// Do something
return param1;
}
When you want to store a returned value from a function, you do something like: var returned = start_battle(param1);
And the fact that you don't know why the modal just hangs, means that you didn't check the browser's error console, which can hold some pretty important information on what's wrong. Try checking that and posting here so we can see the current problem
Your function declaration seems a little off. I think you should leave off the $ from function. Just do this
function start_battle() {
Also, when you're calling a function, you don't say function before it. And if you want to pass a value to the function, you have to put it inside the parenthesis, both when defining the function and when calling it. Like this
function start_battle(someValue) {
// do some stuff with someValue
}
// inside your .click, call start_battle like this
start_battle(passedThisValue);
Pretty basic stuff. But either one of those problems could be causing the hang, which was likely a javascript error.

Creating custom JavaScript object from data returned by jQuery AJAX request

I want to create a custom javascript object which contains data returned from a jQuery AJAX request, but I don't know which is the right way to do it. I was thinking maybe one way could be to include the AJAX request inside the constructor function so the object is created like this:
// Constructor function
function CustomObject(dataUrl) {
var that = this;
$.ajax(dataUrl, {
success: function (json) {
that.data = $.parseJSON(json);
}
});
}
// Creating new custom object
var myObject = new CustomObject('http://.....');
Another way may be to use a function which does the AJAX and then returns the new object based on the data from the AJAX response.
function customObject(dataUrl) {
// Constructor function
function CustomObject(data) {
this.data = data;
}
$.ajax(dataUrl, {
success: function (json) {
var data = $.parseJSON(json);
return new CustomObject(data);
}
});
}
// Creating new custom object
var myObject = customObject('http://.....')
I would like to know what is the best practice when doing something like this, as well as advantages/disadvatages of different methods. Maybe you can point me to some article or example on something similiar to what I am trying to do.
Thanks in advance.
I think this would be a better approach, it makes your CustomObject only knowledgeable about the data it contains. Here you delegate the work of creating objects to a factory, and pass in a callback to get a reference to the created object, since ajax is asynchronous. If you don't mind making it synchronous, then the createCustomObject function can just return the instance, and the callback can be removed.
function CustomObject(data) {
this.data = data;
}
var factory = (function(){
function create(dataUrl, objectClass, callback){
$.ajax({
url: dataUrl,
success: function (data) {
callback(new objectClass(data));
}
});
}
return{
createCustomObject: function(dataUrl, callback){
create(dataUrl, CustomObject, callback);
}
};
})();
// Creating new custom object
var myObject = null;
factory.createCustomObject('http://..', function(customObject){
myObject = customObject;
});
I'd argue that the second method is better because then you only create a new CustomObject once the script is actually fully prepared to do so (i.e. it has the data it needs from the AJAX request).

Unable to change global variable from local function

I'm trying to have a jQuery.getJSON() call change a global variable with the JSON array it returns:
var photo_info ;
//Advance to the next image
function changeImage(direction) {
jQuery('img#preview_image').fadeOut('fast');
jQuery('#photo_main').css('width','740px');
if (direction == 'next') {
jQuery.getJSON('/ajaxupdate?view&sort='+sort+'&a='+a+'&s=' + title_url_next, function(data) {
photo_info = data;
title_url = photo_info.title_url;
title_url_next = photo_info.preview_title_url_next;
title_url_previous = photo_info.preview_title_url_previous;
});
} else if (direction == 'prev') {
jQuery.getJSON('/ajaxupdate?view&sort='+sort+'&a='+a+'&s=' + title_url_previous, function(data) {
photo_info = data;
title_url = photo_info.title_url;
title_url_next = photo_info.preview_title_url_next;
title_url_previous = photo_info.preview_title_url_previous;
});
}
}
However, the variable photo_info is only accessible from within the getJSON() function and returns undefined from anywhere else in the script.
What am I doing wrong?
as Randal said Ajax call is asynchronous. Use the ajaxComplete function or replace the getJSON function with an .ajax call and use the photo_info var whithin the success function e.g.:
$.ajax({
url: 'ajax/test.html',
success: function(data) {
$('.result').html(photo_info);
}
});
If you're looking at photoinfo in the rest of the script right after changeImage has returned, then of course it won't have a value, because the Ajax call is asynchronous. You need to rethink your application to be more event driven.
JavaScript scoping isn't quite like standard scoping. It looks like you're actually losing your scope because of nested functions. Try giving this article a read:
http://www.robertsosinski.com/2009/04/28/binding-scope-in-javascript/

Categories

Resources