I would like to get my data from localStorage, because it is faster and avaible offline, and then get data from web, let's say ajax call.
function getdata(){
function loadViaAjax(){
localStorage.data=newerData;
return newerData;
}
if(localStorage.data){
return localStorage.data;
}
}
toBeInseretIntoDOM=getData(); //AngularJS will do this part
The goal is to get the localStorage.data first, since the user can have slow connection and old informations is still better than none, and simultaneously do the ajax request to get then newest data.
Logicically, the localStorage's data will be faster so they should be returned to be procesed and inserted into DOM, but once the ajax catch up, the data should get updated.
function setdata(data){
//do whatever you need to with your data here
}
function getdata(){
$.get(data_url,function(response){
setdata(response);
});
if(localStorage.data){
setdata(localStorage.data);
}
}
When getdata is called an ajax request will be immediately sent out. Without waiting for a reply the data is set from local storage (if it exists) with setdata. When the ajax request receives a response setdata is called again, but this time with the server data.
If you have a function that sometimes acts asynchronously and sometimes doesn't (or, in your case, always both), then I've found that the best thing to do is to treat it like it's always asynchronous. In other words, pass it a callback and always act on the results from there:
function getdata(callback) {
$.get(data_url, function(response) {
callback(response);
});
callback(localStorage.data);
}
Use it like this:
getdata(function(data) {
// do something
});
Note that the callback doesn't have to care whether the data was retrieved synchronously or not. It can just act on the data it receives.
A similar pattern is to return the data if you have it and go get it if you don't:
function getdata(callback) {
if (localStorage.data) {
callback(localStorage.data);
} else {
$.get(data_url, function(response) {
callback(response);
});
}
}
I sounds like you are saying ...
I want to keep the last copy of the data available in localStorage, but once in a while I want to see if I can freshen that data by Ajax.
If that is the case, then you could so something like..
// This is not complete code ...
function loadData(callback) {
getFromCache() {
var data = window.localStorage.getItem("mystuff");
if (data) {
callback(JSON.parse(data));
}
}
handleSuccess(data) {
window.localStorage.setItem("mystuff", JSON.stringify(data));
callback(data);
}
var ajaxConfig = {
url: "http://example.com",
error: getFromCache,
success: handleSuccess
}
// Trigger ajax call here...
// You can even use a window.setTimeout() here
// to see if the ajax event takes too long -- if so
// cancel it and call getFromCache
}
Related
I'm experimenting with JQuery and trying to create a function to get dynamic data from a JSON returned API and store it in a global variable (I don't know if this is the right/best way to do this).
What I have so far is
function getdata(url){
var data = $.ajax({
type: 'GET',
url: url
});
return data;
};
So far everything works fine, but this returns an object with a "responseJSON" key and I can't seem to find a way to navigate to this key and then do a $.each loop through the arrays in it.
So the questions are:
Is this the right / way ( if not please explain your answer)
How do you navigate through a multidimensional object containing arrays in the "responseJSON" key.
Another approach is to pass a callback to your function so you can set the response handler within the function and less code when you call your getData method
function getdata(url, callback){
var data = $.ajax({
type: 'GET',
url: url
}).done(callback).error(function(){
alert('Oppps...something went wrong')
});
return data;
};
getData('urlstring', function(data){
/* doSomething with data */
})
AJAX is asynchronous. That means it runs in the background while the rest of your script runs. At a point in the future when the AJAX call completes, then you can access it.
In jQuery, $.ajax returns a promise. So what you can do is the following:
getdata('/path/to/your.json').done(function(data){
// Use your JSON data here
console.log(data);
});
What happens is that once the AJAX call is done, your .done() function will run and you will have access to the data returned.
Don't try to access the properties of the $.ajax object (the responseJSON won't be populated until the call is finished). Use callbacks to get at the returned data.
If you want the json data to be in global scope, just define a global variable (that is, outside the function), and then in the function fill it with the returned data. Something like so:
var api_response;
function get_data(url) {
$.post(url, function(j) { api_response = j; }, "json");
// or
$.getJSON(url, function(j) { api_response = j; });
}
You don't even need to create a function for this and can use jquery's own $.getJSON (the or case).
I have a application where there are numerous number of ajax calls to the server.
Now I want to audit the response that comes from the server (This requirement poped up after the ajax code was laid).
So I have a function that would audit the response data, only problem is how can I get the data to be sent to the function which now sits separately.
I don't want to do the laborious work of adding the line of code for calling the function in each ajax call.
Is there easier and general way out. Somehow I could detect when a response come back and then process the response.
Using both traditional javascript method as well as jquery ajax calls in the system. (The app has been getting changes from a long time and has changed hands a lot so the new things get added and the older ones never get removed)
Wrap your ajax calls with a helper function and use it throughout your code.
An (untested) example:
MyApp = MyApp || {
logRequest: function _logRequest(settings, response) {
// Log your response
},
ajax: function _ajax (settings) {
var that = this;
// Log attempt request here?
// Example of logging the success callback (do similar for error or complete)
if (settings.success) {
// A success handler is already specified
settings.success = function (data) {
that.logRequest(settings, data); // Log the response
settings.success(data); // Call the original complete handler
};
} else {
// No success handler is specified
settings.success = function (data) {
that.logRequest(settings, data);
};
}
return jQuery.ajax(settings);
}
};
I favour this mechanism for lots situations where I want to reduce boilerplate. I only have to modify the state of the MyApp object which is my own (named appropriately for the application), so it is sort of an interface that allows you to intercept function calls without modifying other global objects. You can also swap this functionality out with something else very easily without having to update your references everywhere, which could be useful in a lot of other situations as well.
Using .ajaxComplete() should be enough to catch the onComplete event for all AJAX requests made through jQuery. Isn´t that what you´re asking for?
$('.ajaxRequest').click(function(event) {
event.preventDefault();
$.getJSON(
'/echo/json/',
this.id,
function(data, textStatus, jqXHR) {
console.log(data, textStatus, jqXHR);
}
);
});
// Listen to all ajax requests
$("#log").ajaxComplete(function(event, request, settings) {
console.log(event, request, settings);
});
View demo.
I have a need to collect data from multiple sources (xml or JSON format) via AJAX, and then run a function that consumes these data sets.
How can I check that all the AJAX calls are successful before the function is executed? Ideally, I'd like to keep async calls to minimize the response time.
Conceptually, it would work like this:
Use async calls.
Code a success handler for each call.
When a call succeeds, you store the data from it in some common place and then record that this call has finished.
At the end of each success handler, you check to see if all data is available now and, if so, you can a function to consume it.
Some pseudo code for an ajax call:
results = [];
$.ajax({
// other parameters here
success: function(data) {
results.push(data);
checkResults();
};
});
function checkResults() {
// if all five results are in, then we're ready to process them
if (results.length >= 5) {
processResults(results);
}
}
I am making a chrome extension which sets a cookie when users log in. When I attempt to read the cookie using the chrome.cookies.get() method the callback can log the results but I cant pass it out of the callback.
function getCookie (cookieName){
var returnVal;
chrome.cookies.get({
'url':'https://addictedtogether.com/',
'name':cookieName
},
function(data){
console.log(data); //log displays returned cookie in a object
returnVal=data;
}
);
console.log(returnVal); //log says this is undefined
return returnVal;
}
I tried using a couple different ways of passing the result but it seems like the object is undefined unless it is called from within the callback.
The problem is that your callback is called after the main function returns. (The extension APIs are called asynchronous for a reason!) returnVal is undefined because it hasn't been assigned to yet. Try modifying your function to accept a callback argument:
function getCookie (cookieName, callback){
chrome.cookies.get({
'url':'https://addictedtogether.com/',
'name':cookieName
},
function(data){
callback(data);
});
}
// Use like this:
getCookie("CookieName", function(cookieData){
// Do something with cookieData
});
If you don't like passing callbacks around, you could also modify your function to return a deferred. If you have to handle a lot of asynchronous function calls, deferreds make your life a lot easier. Here's an example using jQuery.Deferred:
function getCookie (cookieName){
var defer = new jQuery.Deferred();
chrome.cookies.get({
'url':'https://addictedtogether.com/',
'name':cookieName
},
function(data){
defer.resolve(data);
});
return defer.promise();
}
// Example use:
getCookie("FooBar").done(function(data){
// Do something with data
});
function isNewUsername(str){
var result;
$.post('/api/isnewusername',
{username:str},
function(data) {
result = data.result;
},
"json");
return result;
}
So , my problem is very simple but I can not figure it out . I want to access result from the isnewusername function . I am very curious about answer because I spent 1 hour on it .
Thank you
It cannot be done the way you're doing it, as ajax queries are asynchronous (meaning, they don't block, and the result will not come instantly, it'll come when the server actually responds). You'll have to call another function with the results (or otherwise, only do something with the results once they are actually available).
For instance:
function isNewUsername(str){
$.post('/api/isnewusername',
{username:str},
function(data) {
someOtherFunction(data.result);
},
"json");
}
As a quick note when you use the jQuery post function you are using a shorthand form of the jQuery ajax function which means you are doing an asynchronous call. Therefore only on a successful response is jQuery going to call your function and put the result from your server side call in the data parameter of your success callback.
To illustrate:
function isNewUsername(str){
$.post('/api/isnewusername',
{username:str},
function(data) {
alert(data.result);
},
"json");
}
That said you can change your code to specify a synchronous callback but that has the potential to lock the users browser until the request is returned.