How to use callbacks in other functions in JavaScript? [duplicate] - javascript

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 4 years ago.
I am stuck with how to use the variable inside a callback function from another function that is outside of callback...
Simple explanation of problem:
There is function that gets json from web. It takes some arguments already. On success, callback manipulates the data slightly. Now, another function responsible for updating the chart is meant to get the manipulated data from callback and do its own thing...
My code:
var mainData;
function getMainData (city, callback) {
this.city = city;
var url = "http://api.openweathermap.org/data/2.5/weather?q=appid=7ce3e1102e1902e0f878c2a640e95aed&london";
$.ajax ({
method: "GET",
type: "json",
cache: "false",
url: url,
success: callback
})
};
function callback (data) {
mainData = data;
var dArray = data.list.map(a=>a.dt)
var tempMinArray = data.list.map(a=>a.main.temp_min)
var tempMaxArray = data.list.map(a=>a.main.temp_max)
}
function changeChart (chartName, howToPassTempMinArrayHere?) { // <--- this is where I have no idea how to pass callbacks variables
chartName = chart.name.(....);
someDataFromMainData = chart.data.(....);
};
// on click of button (...) :
(
getMainData(callback); // why no action?? nothing??
changeChart (myChart, someDataFromMainData)
);

Just put the callback in the function like this:
var mainData;
function getMainData (city, callback) {
this.city = city;
var url = "http://api.openweathermap.org/data/2.5/weather?q=appid=7ce3e1102e1902e0f878c2a640e95aed&london";
$.ajax ({
method: "GET",
type: "json",
cache: "false",
url: url,
success: callback
})
};
function callback (data) {
mainData = data;
var dArray = data.list.map(a=>a.dt)
var tempMinArray = data.list.map(a=>a.main.temp_min)
var tempMaxArray = data.list.map(a=>a.main.temp_max)
// Put your code here
changeChart (myChart, someDataFromMainData)
}
function changeChart (chartName, howToPassTempMinArrayHere?) { // <--- this is where I have no idea how to pass callbacks variables
chartName = chart.name.(....);
someDataFromMainData = chart.data.(....);
};
// on click of button (...) :
(
getMainData(callback); // why no action?? nothing??
);

Related

Issue accessing variable outside of function scope [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 6 years ago.
I'm pulling data from an XML feed. That is all working correctly but I need productIDs available outside the function.
// Get feed data
$.get('example-feed.xml', function (data) {
var $xml = $(data);
// Collect array of product IDs
var productIDs = [];
// extract ids from xml
$xml.find("item").each(function() {
var $this = $(this)
item = {
id: $this.find("id").text()
}
// get the id
var itemID = item.id;
// push ids to array
productIDs.push(itemID);
});
console.log(productIDs); // Works as expected
});
console.log(productIDs); // Undefined, also as expected
How can I adjust my function to work like that?
example = function(){
var productIDs = "my content ids"
return {'productIDs': productIDs}
}
var retrive = example();
console.log(retrive.productIDs);
There are multiple ways you can do this, but the best thing here is to use promises, because JQuery's get is usually asynchronous function and you have to wait for it's completion to get product ids
You may do it like this
function fetchThings () {
return new Promise(function (yes, no) {
$.get('example-feed.xml', function (data) {
// some code here
console.log(productIDs); // Works as expected
yes(productIDs);
});
});
}
fetchThings().then(function (productIDs) {
// do stuff with prodcut ids here
});
The other way to do it would be making your $.get call synchronous, so replace it by
var productIDs;
$.ajax({url: 'example-feed.xml', type: "GET", async: false, success: function (data) {
// process productIDs here
}});
// use productIDs here
Update:
Here is a snippet of async ajax, click run to check
var postIDs;
$.ajax({
url: 'http://jsonplaceholder.typicode.com/posts',
method: 'GET',
async: false,
success: function(posts) {
postIDs = posts.map(function (p) { return p.id; });
}
});
document.write(JSON.stringify(postIDs));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

javascript variable is not showing correct value [duplicate]

This question already has answers here:
How to add callback to AJAX variable assignment
(4 answers)
Closed 8 years ago.
i have this ajax call function.
function saveData(ip)
{
$JQ.ajax({
type: "POST",
url: "all_actions.php",
data:
{
page_url:document.URL,
ip_address:ip
},
success: function(responce)
{
if(responce)
{
var newtoken;
newtoken=responce;
return newtoken;
}
}
});
}
Then i have another function
function getToken()
{
var ip=myip
var mytoken;
mytoken=saveData(ip);
alert(mytoken);
}
My token giving undefined in alert.Although if i alert newtoken variable in savedata response it gives correct value in alert box.why if i return that avlue it does not assigned to mytoken.
is it something time delay issue.??
Need your help...
You cannot return from an asynchronous call.
You have to consume the return data inside the success function. Whatever you are going to do with token, write that code inside the success handler.
success: function(responce)
{
if(responce)
{
var newtoken;
newtoken=responce;
// Global variable
sourceid = newtoken;
return newtoken; // This won't work
}
}
Also
function getToken()
{
var ip=myip
var mytoken;
mytoken=saveData(ip); // This won't return any data
alert(mytoken); // This won't give you anything useful
}
Hi friends This is solution that for i was looking.
function saveData(ip)
{
return $JQ.ajax({
type: "POST",
url: "all_actions.php",
data:
{
page_url:document.URL,
ip_address:ip
},
async: false,
}).responseText;
}
function getToken()
{
var ip=myip
var mytoken;
mytoken=saveData(ip);
return mytoken;
}
The first 'A' in AJAX is 'Asynchronous'. Your alert is running before the AJAX request has had a chance to complete. You need to handle whatever you wish to do with the response inside of the success: function() or .done() functions of jQuery:
success: function(responce)
{
if(responce)
{
var newtoken = responce;
// Work here with newtoken...
}
}

Javascript - using in function defined variable

I want to execute this function and use the variable outside the function, but inside an each function. How can I get this to work?
$('.social').each(function() {
url = "http:www.google.com";
bit_url(url);
$(element).append(urlshortened);
});
function bit_url(url) {
var url = url;
var username = "...";
// bit.ly username
var key = "...";
$.ajax({
url : "http://api.bit.ly/v3/shorten",
data : {
longUrl : url,
apiKey : key,
login : username
},
dataType : "jsonp",
success : function(v) {
urlshortened = v.data.url;
}
});
}
The "A" in Ajax stands for Asynchronous code won't work like that, you need callbacks.
function bit_url(url) {
[...]
//return the Deffered object
return $.ajax({ [...]
}
$('.social').each(function() {
[...]
//attach a `done` callback to the returned $.ajax's Deferred instance
bit_url(url).done(function(v) {
$(element).append(v.data.url);
});
});
Deferred.done is an equivalent to $.ajax's success, I've attached the done handler inside the .each scope so your callback can access all variables from the .each scope.
Though, if $(element) is always the same element, you will be fine with #JohnJohnGa's answer by putting the append inside the success handler.
I assume you want to replace anchors' href inside the .each due to the question nature, so you'd store a reference to the link inside of the .each and use that reference inside the callback.
You can append the result in the success function
success: function (v) {
urlshortened = v.data.url;
$(element).append(urlshortened)
}
So your code will be:
$('.social').each(function () {
url = "http:www.google.com";
bit_url(url);
});
function bit_url(url) {
var url = url;
var username = "...";
// bit.ly username
var key = "...";
$.ajax({
url: "http://api.bit.ly/v3/shorten",
data: {
longUrl: url,
apiKey: key,
login: username
},
dataType: "jsonp",
success: function (v) {
$(element).append(v.data.url);
}
});
}

Passing a callback function with included parameters? [duplicate]

This question already has answers here:
Pass an extra argument to a callback function
(5 answers)
Closed 6 years ago.
I have this below code..
function getGrades(grading_company) {
if (grading_company == 'Not Specified') {
// Remove grades box & show condition box
showConditionBox();
} else {
// Set file to get results from..
var loadUrl = "ajax_files/get_grades.php";
// Set data string
var dataString = 'gc_id=' + grading_company;
// Set the callback function to run on success
var callback = showGradesBox;
// Run the AJAX request
runAjax(loadUrl, dataString, callback);
}
}
function runAjax(loadUrl, dataString, callback) {
jQuery.ajax({
type: 'GET',
url: loadUrl,
data: dataString,
dataType: 'html',
error: ajaxError,
success: function(response) {
callback(response);
}
});
}
Edit: Here is the function that gets called as the callback function:
function showGradesBox(response) {
// Load data into grade field
jQuery('#grade').html(response);
// Hide condition fields
jQuery('#condition').hide();
jQuery('#condition_text').hide();
// Show grade fields
jQuery('#grade_wrapper').show();
jQuery('#grade_text_wrapper').show();
}
Now if I wanted to pass the grading_company variable to the callback function as a parameter is there a way to do that without having to add it as another parameter in the runAjax call? I'm trying to keep the runAjax function open to other usage so I don't want to pass in any extra parameters; but if it can somehow be included within the callback then great.
change your callback to an anonymous function:
// Set the callback function to run on success
var callback = function () {
showGradesBox(grading_company);
};
This allows you to pass parameters to the inner function.
Edit: to allow for the ajax response:
// Set the callback function to run on success
var callback = function (response) {
showGradesBox(grading_company, response);
};
Another possibility is instead of doing dataString do dataObject then pass that object to the callback. Like so:
function getGrades(grading_company) {
if (grading_company == 'Not Specified') {
// Remove grades box & show condition box
showConditionBox();
} else {
// Set file to get results from..
var loadUrl = "ajax_files/get_grades.php";
// Set data object
var dataObject = {
'gc_id' : grading_company
/*to do multiples..
'item1' : value1,
'item2' : value2,
'etc' : etc */
}
// Set the callback function to run on success
var callback = showGradesBox;
// Run the AJAX request
runAjax(loadUrl, dataObject, callback);
}
}
function runAjax(loadUrl, dataObject, callback) {
jQuery.ajax({
type: 'GET',
url: loadUrl,
data: $.param(dataObject),
dataType: 'html',
error: ajaxError,
success: function(response) {
callback(response, dataObject);
}
});
}
Note the addition of $.param().
Then in the callback function, you should know what data you're after. If function setGrades(resp, data) { ... } was the callback, then you can access the values in setGrades
function setGrades(resp, data) {
alert( data.gc_id);
}
EDIT
After testing, I realize that $(dataObject).serialize() will not work. So I've updated to use $.param(). Please see this SO post for more info.

Issue with code inner variable

I have a code like the one stated below, please how do I get the value for (getData), using a code like:
var instanceArray = myGraph.getInstances(component)
I was thinking myGraph.getInstances(component).getData will do it, but it failed
this.getInstances = function(component) {
var getData = {};
$.ajax({
url: "/rpc/alerts2/commonObj_rpc.cfc?method=getInstances",
data: {"component":component},
type: "POST",
async: true,
success: function(data) {
getData = $.parseJSON(data);
console.log("hey");
var $render_component_instance = $("#instances").empty();
$("#instances").append($("<option />").val("all").text("All Instances (Summed)"));
$.each(getData, function (cIndex, cItem){
var $instance = $("<option />").val(cItem.si_instance).text(cItem.si_label.toUpperCase());
$render_component_instance.append($instance);
})
$("#instances").multiselect("refresh");
}
});
};`
You can't, the get is asynchronous. getInstances returns before the GET completes, so it's impossible for getInstances to return the data. (See further note below.)
You have (at least) three options:
Use a callback
Return a blank object that will get populated later, and have the code that needs it poll it periodically
Use a synchronous get (not a good idea)
1. Use a callback
What you can do instead is accept a callback, and then call it when the data arrives:
this.getInstances = function(component, callback) {
$.ajax({
url: "/rpc/alerts2/commonObj_rpc.cfc?method=getInstances",
data: {"component":component},
type: "POST",
async: true,
success: function(data) {
var getData = $.parseJSON(data);
console.log("hey");
var $render_component_instance = $("#instances").empty();
$("#instances").append($("<option />").val("all").text("All Instances (Summed)"));
$.each(getData, function (cIndex, cItem){
var $instance = $("<option />").val(cItem.si_instance).text(cItem.si_label.toUpperCase());
$render_component_instance.append($instance);
})
$("#instances").multiselect("refresh");
callback(getData);
}
});
};
And call it like this:
myGraph.getInstances(component, function(data) {
// Use the data here
});
2. Return a blank object that will get populated later
Alternately, you can return an object which will be blank to start with, but which you'll add the data to as a property later. This may be closest to what you were looking for, from your comments below. Basically, there's no way to access a function's local variables from outside the function, but you can return an object and then add a property to it later.
this.getInstances = function(component) {
var obj = {};
$.ajax({
url: "/rpc/alerts2/commonObj_rpc.cfc?method=getInstances",
data: {"component":component},
type: "POST",
async: false, // <==== Note the change
success: function(data) {
var getData = $.parseJSON(data);
console.log("hey");
var $render_component_instance = $("#instances").empty();
$("#instances").append($("<option />").val("all").text("All Instances (Summed)"));
$.each(getData, function (cIndex, cItem){
var $instance = $("<option />").val(cItem.si_instance).text(cItem.si_label.toUpperCase());
$render_component_instance.append($instance);
})
$("#instances").multiselect("refresh");
// Make the data available on the object
obj.getData = getData;
}
});
return obj; // Will be empty when we return it
};
And call it like this:
var obj = myGraph.getInstances(component);
// ...later...
if (obj.getData) {
// We have the data, use it
}
else {
// We still don't have the data
}
3. Use a synchronous get
I do not recommend this, but you could make the call synchronous. Note that synchronous ajax requests will go away in a future version of jQuery. But just for completeness:
this.getInstances = function(component) {
var getData;
$.ajax({
url: "/rpc/alerts2/commonObj_rpc.cfc?method=getInstances",
data: {"component":component},
type: "POST",
async: false, // <==== Note the change
success: function(data) {
var getData = $.parseJSON(data);
console.log("hey");
var $render_component_instance = $("#instances").empty();
$("#instances").append($("<option />").val("all").text("All Instances (Summed)"));
$.each(getData, function (cIndex, cItem){
var $instance = $("<option />").val(cItem.si_instance).text(cItem.si_label.toUpperCase());
$render_component_instance.append($instance);
})
$("#instances").multiselect("refresh");
}
});
return getData;
};
And call it like this:
var getData = myGraph.getInstances(component);
But again, I don't advocate that. Synchronous ajax calls lock up the UI of the browser, leading to a bad user experience.

Categories

Resources