This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 3 years ago.
I'm trying to return an object inside a callback function
In the following situation, the console.log() show the result as expected
var dVizModule = (function(){
let dataset;
function loadData(fileName) {
dataset = d3.csv(fileName, (data) => {
dataset = data;
console.log(dataset);
});
};
return {
loadData: loadData
}
})();
dVizModule.loadData("data/time_scale_data.csv")
but when I try to use return in callback function the story is different and it returns undefined
var dVizModule = (function(){
let dataset;
function loadData(fileName) {
dataset = d3.csv(fileName, (data) => {
dataset = data;
return dataset;
});
// return dataset; or even here!
};
return {
loadData: loadData
}
})();
console.log(dVizModule.loadData("data/time_scale_data.csv"))
Since its a callback based workflow, the code above won't work. d3.csv is an asynchronous function, you can only get the result through a callback passed to it and hence even loadData needs to follow the same pattern.You just need to write something like this.
var dVizModule = (function(){
function loadData(fileName,callback) {
d3.csv(fileName, (data) => {
callback(data);
});
};
return {
loadData: loadData
}
})();
dVizModule.loadData("data/time_scale_data.csv",(data)=>{
console.log(data);
})
Related
The system I'm working with was designed to only make synchronous ajax calls, so i am looking for a workaround. First i have an ajax call that is wrapped in a function. I then wrap it in another function so it doesn't get executed when adding it to the array. So i have two arrays of async ajax call functions. I would like to execute everything in the first array, and then wait until everything has completed. I would then like to execute everything in a second array. This is what i have so far
I have a loop that goes through items and I have a wrap function for each item that takes in my already wrapped ajax call so that it doesn't get executed and stores it in an array like below
var postpromises = [];
var WrapFunction = function (fn, context, params) {
return function () {
fn.apply(context, params);
};
}
var postPromise = WrapFunction(ajaxFunction, this, [{
url: url,
data: j,
async: true,
type: 'POST',
success: function (data) {
//success
},
error: function (xhr, textStatus, errorThrown) {
//error
}
}]);
postpromises.push(postPromise);
I then have the same code for validation. So before I move on to next page, I have the following
$.when.apply(undefined, postpromises).then(function () {
console.log();
$.when.apply(undefined, validatepromises).then(function () {
console.log();
});
});
The issue is that when I get to the code above, none of my postpromises even get executed, so I feel like I may be missing something here.
Ideas?
The function $.when require a promise, in your code you are returning a function that return nothing, so just return the result of the wrapped function:
ES6 spread operator REF
function arguments object REF
var postpromises = [];
var validatepromises = [];
function f1() {
var fakePromise = $.Deferred();
setTimeout(() => {
fakePromise.resolve("IM RESOLVED!!");
}, 500);
return fakePromise.promise();
}
//OLD ONE
/*var WrapFunction = function (fn, context, params) {
return function () {
fn.apply(context, params);
};
}*/
var WrapFunction = function(fn, context, params) {
return function() {
return fn.apply(context, params);
}();
}
var postPromise = WrapFunction(f1, this, []);
postpromises = [postPromise];
var validatePromise = WrapFunction(f1, this, []);
validatepromises = [validatePromise];
//OLD ONE
/*$.when.apply(undefined, postpromises).then(function(res) {
console.log(res);
$.when.apply(undefined, validatepromises).then(function(res) {
console.log(res);
});
});*/
$.when.apply(null, [...postpromises, ...validatepromises]).then(function() {
console.log([].slice.call(arguments))
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I'm new to JavaScript and i'm having difficulties understanding callback functions.
I have a function below that returns an array and then another function that calls the first function. Problem is, the array in the second function is always undefined, even though in the first function is returns an array of objects.
function getItems() {
$.get(url,
function(data) {
var obj = $.parseJSON(data);
var itemArr = $.map(obj, function(ele) { return ele; })
return itemArr;
});
}
function alertTest() {
var items = getItems();
alert(items);
}
I understand that the first function is asynchronous and so that the alert in the second function is called before the returned array, which causes the second function to alert an undefined object.
I'm aware there is quite some documentation around this but i'm having trouble understanding how it works. Could someone show me the changes i would need to make so that the alertTest function returns the populated array after the getItems function has been called?
Thanks in advance!
$.get is an async function. which means the callback function is invoked when the is hit and the response is returned inside .
Now return itemArr is actually returned by the callback function and
getItems() doesn't actually return anything and hence it is always undefined.
For your code to work,
function getItems() {
$.get(url,
function(data) {
var obj = $.parseJSON(data);
var itemArr = $.map(obj, function(ele) { return ele; })
alertTest(itemArr);
return itemArr;
});
}
this would call alertTest function.
One way to do this would be to use JS Promises like so
function getItems() {
return Promise.resolve(
$.get(url,
function (data) {
var obj = $.parseJSON(data);
var itemArr = $.map(obj, function (ele) {
return ele;
})
return itemArr;
}));
}
function alertTest() {
var items = getItems().then(function (items) {
alert(items);
});
}
It is a hard one to get your head around. Promises allow you to write code that runs in a sequence like sync code.
You could insert callbacks into the function and have that call when the get request finishes like shown in the other answer by Rhea but this is a cleaner way to do this and Promises are now part of the Javascript language.
function getItems() {
$.get(url, function(data) {
var obj = $.parseJSON(data);
var itemArr = $.map(obj, function(ele) { return ele; })
alertTest(itemArr);
});
}
function alertTest(items) {
alert(items);
}
getItems();
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 5 years ago.
I have the following code:
function test() {
$.when(MyModule.loadData("breadcrumbs", "BreadcrumbsData", jsndata, 'GET')).then(
function (data) {
return data;
});
}
var result = test();
Problem: I am not getting the data in 'result' variable.
I am using Jquery 3.x.
MyModule.loadData is a method that executes a synchronous ajax request and returns the jqXHR object.
Thanks.
function test() {
return $.when(MyModule.loadData("breadcrumbs", "BreadcrumbsData", jsndata, 'GET')).then(
function (data) {
return data;
});
}
var result;
test().then(function(data){
result = data;
}).then(function(){
console.log(result);
});
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
How to return value from an asynchronous callback function? [duplicate]
(3 answers)
Closed 6 years ago.
I have a basic function in protractor written as :
this.getCurrentUrl = function () {
browser.getCurrentUrl().then(function(url){
console.log('url : '+url);
});
};
Now is there a way I can access the 'url' outside of the inner function scope, because I need to return this value to some other function calling this one. I need to get the value and return it from outside of then(function(url){...}
the url will be acquired async, so you can't just assign it. You probably want to hand it a callback.
function handleUrl(url) {
// here is where you do something with the url
}
// let your callback be called
this.getCurrentUrl = function(fn) {
browser.getCurrentUrl().then( function (url) {
fn(url);
})
}
// make the call with your handler
this.getCurrentUrl(handleUrl);
Another approach is to have your function return a "container" and that gets inflated later. Then later you can check your container. Since the behavior is async, you won't know when it will be ready, so you can check for it on an interval or something...
// return a container object
this.getCurrentUrl = function() {
var urlContainer = {};
browser.getCurrentUrl().then( function (url) {
urlContainer.url = url;
});
return urlContainer;
}
var urlContainer = this.getCurrentUrl(); // starts off as an empty object
urlContainer.url // undefined
// then shortly in the future
urlContainer.url // has some url
Yet a third way is to return a closure
this.getCurrentUrl = function() {
var urlValue;
browser.getCurrentUrl().then(function(url) {
urlValue = url;
});
return function() {
return urlValue;
}
}
var getUrl = this.getCurrentUrl();
getUrl(); // initially, returns undefined;
// keep trying. then shortly in the future...
getUrl(); // now has the url
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 7 years ago.
I can't get my head around how to return the value from uniqueCheck() to isValid. I've added in a setTimeout to simulate the async operation.
function isValid(data) {
uniqueCheck(data, function(val) {
return val;
//true
});
// need the value here
}
function uniqueCheck(data, cb) {
// do something with data async
setTimeout(function () {
cb(true)
}, 1000);
}
console.log(isValid("some data"));
To use asynchronous calls in your code you can use Promises or for example if you use jQuery you can make use of Deferred object.
//async function using $.Deferred
function asyncFunction(){
var dd = $.Deferred();
setTimeout(function(data) {
dd.resolve('loaded');
}, 500);
return dd.promise();
}
//somwhere in your code
asyncFunction().then(function(value){
//do stuff when Deferred object is resolved
//value = 'loaded'
})
in your code:
function isValid(data) {
uniqueCheck(data).then(function(){
//value is available here
});
// but not here
//because this code is executed earlier then callback
}
function uniqueCheck(data, cb) {
var dd = $.Deferred();
// do something with data async
setTimeout(function () {
cb(true)
}, 1000);
return dd.promise();
}
you have to return the result through an callback function
function isValid(data, callback) {
uniqueCheck(data, function(val) {
callback(true);
return val;
//true
});
// need the value here
}
function uniqueCheck(data, cb) {
// do something with data async
setTimeout(function () {
cb(true)
}, 1000);
}
//console.log(isValid("some data"));
isValid("some data", function(value){
console.log(value);
});