Reputation: 423
I am having some trouble implementing a callback into my JavaScript that uses AJAX. First off, the script reads from a file and places into a variable:
jQuery.get('userdata/' + username + '.txt', function(data) {
var userid = data;
});
Then that variable is being used in the following function, which reads from a .json file and picks the result that only contains the value in userid
.
function loadContacts(filter) {
var contacts = (function () {
var contacts = null;
$.ajax({
'url': 'userdata/' + username + '.json',
'dataType': "json",
'success': function (data) {
contacts = data;
contacts = contacts.filter(function(i) {
return i.id == userid;
});
}
});
return contacts;
})();
// some code for (filter) here
}
The problem here is that before jQuery has had time to create userid
and read from the file specified, the loadContacts
function is already trying to read from userid
so it comes back with an unidentified variable error.
I have spent the last 2/3 hours trying to learn how to implement a callback in AJAX, but I have had no luck after trying quite a few different variations.
I understand that by implementing a callback, essentially I am delaying the loadContacts
function to wait for a success message back from jQuery.get
, so it doesn't try looking for userid
before it has been created, I just can't seem to get it to work.
Could anyone help me?
I have already tried learning from that duplicate post but I don't get it?
Upvotes: 0
Views: 58
Reputation: 3593
How about a little excursion into promises
to fetch data asynchronously, synchronize these calls and process the data.
//creating a few "promises"
var pUserId = $.get('userdata/' + username + '.txt');
var pData = $.ajax({
'url': 'userdata/' + username + '.json',
'dataType': "json"
});
//filter pData by pUserId, as soon as both are available
var pUserdata = $.when(pUserId, pData).then(function(userId, data){
return data.filter(function(item){
return item.id === userId
})
});
//just log these three, as soon as they are available
$.when(pUserId, pData, pUserdata).done(function(userId, data, userdata){
console.log("userId:", userId);
console.log("data:", data);
console.log("userdata:", userdata);
});
And it's up to you, how you want to wrap that into specific functions.
And don't mix a filter with a function that executes an ajax-call. Because then you have to make an ajax-call every time you want a subset of this data. Separate the refreshing of the data and the filtering.
Upvotes: 0
Reputation: 287
easiest way would be to call the loadContacts function from within the result of the first get request.
var filter = function(){...};
var contacts = false;
jQuery.get('userdata/' + username + '.txt', function(data) {
var userid = data;
contacts = loadContacts(filter);
});
You could also make use of the deferred functions of jQuery
Upvotes: 0
Reputation: 337714
As the AJAX request is asynchronous you are returning a value from your loadContacts()
function before any data is received. You need to pass a callback function to the function which can be executed after the AJAX request completes. Something like this:
function loadContacts(filter, callback) {
$.ajax({
url: 'userdata/' + username + '.json',
dataType: "json",
success: function (data) {
var contacts = data.filter(function(i) {
return i.id == userid;
});
callback && callback(contacts);
}
});
}
function doSomethingWithContacts(contacts) {
console.log(contacts);
}
loadContacts('foo', doSomethingWithContacts);
Upvotes: 2