Extend $.getScript to enable cache locally - javascript

What is the correct way to extend jQuery's getScript method to enable cache only inside that function for the ajax request?
I need to use this in my application to avoid unnecessary request for various scripts. Also is it correct to override this method or should I name the new function differently.
What I came up with is
jQuery.getCachedScript = function( url, callback, options ) {
// Allow user to set any option except for dataType, cache, and url
options = $.extend( options || {}, {
dataType: "script",
cache: true,
url: url,
success: callback
});
// Use $.ajax() since it is more flexible than $.getScript
// Return the jqXHR object so we can chain callbacks
return jQuery.ajax( options );
};
using the example form https://api.jquery.com/jQuery.getScript/. Is it correct, and can I name this getScript to override the jQuery method.
Would it be preferred to instead of using cache: true (or additionally) to use a global array that stores the .js files URLs and check against it for every call. I wrapped all the javascript code in this files in a function that I can call with different arguments using the getScript callback.

Related

Can I cache contents loaded by jQuery.getScript()

As per jQuery documentation (https://api.jquery.com/jquery.getscript/) use more flexible $.ajax() method, but it doesn't work for me described in here (jQuery cannot load plugin file using ajax before calling the plugin function, thus, gives kind of weird result)
By default, $.getScript() sets the cache setting to false. This
appends a timestamped query parameter to the request URL to ensure
that the browser downloads the script each time it is requested. You
can override this feature by setting the cache property globally using
$.ajaxSetup():
$.ajaxSetup({
cache: true
});
But I need to cache few of the contents not all.
Alternatively, you could define a new method that uses the more
flexible $.ajax() method.
It didn't work for me as it doesn't guarantee loading files in a sequence.
Now what is the best solution for this situation?
$.getScript({
url: "foo.js",
cache: true
})
Supported on jQuery 1.12.0 or later
use $.ajax with dataType: 'script' and cache: true.
$.ajax({
cache: true,
url: 'foo.js',
dataType: 'script', // optional, can omit if your server returns proper contentType for js files.
success: function () {
console.log('Hello World!');
}
});
This assumes your server is responding with the headers required for the browser to cache the file.

Adding a settings file to a front-end web application in an async manner

I'm currently trying to resolve some with an SPA being built with a lot of custom components, borrowing a lot from all over the place.
The current challenge I have is initializing some settings (Endpoint URLs and the sort) with a settings file to be set on a per-deployment basis. It's Javascript, so it makes sense to relegate this to a JSON file. However, a lot of the logic is still written in this strongly-defined OO methodology, and I am trying to determine the best method to load this settings file within the async methodology.
Looking at other topics on Stack Overflow, the jQuery getJSON method is a viable option. But I am not clear if it is still based on synchronous calls. Furthermore, If there is an async option, I want to be sure that the value is loaded before firing any additional logic in the application (instead of having it initialize nothing at the constructor).
Is my assumption correct? Is getJSON the best approach here? Code is listed below.
var settings = $.getJSON("conf.json");
var SearchObject = new Search(settings);
// Remainder is just a bunch of bind() and on() calls
$.getJSON is just a shortcut for more detailed $.ajax call where you can adjust much more parameters, like callback if you need. And no, $.getJSON same as $.ajax
Perform an asynchronous HTTP (Ajax) request.
http://api.jquery.com/jQuery.ajax/
The getJSON jquery function is async by default.
$.getJSON({
url: url,
data: data,
success: function(data, textStatus, jqXHR ){}
});
It is the same as:
$.ajax({
dataType: "json",
url: url,
data: data,
success: function(data, textStatus, jqXHR ){}
});
But, with the ajax function you can set async to false if you want.
eg.
$.ajax({
dataType: "json",
async: false,
url: url,
data: data,
success: function(data, textStatus, jqXHR ){}
});

jQuery $.when().done() not working as expected with JSONP when loading a local .json file

I'm building an SPA using Sammy and Knockout powered by a REST Web Service available on a different URL.
I'm noticing some odd behavior when returning JSONP versus JSON when using $.when().done()...
.done() never fires, but .fail() will, even though the status code I receive is 200, and JSONP Linter tells me that my JSONP is valid:
(function($) {
$(function() {
$.when($.getJSON('endpoint1?callback=?', null),
$,getJSON('endpoint2?callback=?', null))
.done(function(resp1, resp2) {
console.log(resp1); // this is never called
});
})
.fail(function(obj) {
console.log(obj); // this is called, but why?
});
});
})(jQuery);
A sample response returned is:
callback({
"external-links": [
{
"nav_link_text": "Stack Overflow",
"url": "http://stackoverflow.com"
}
]
});
If I return JSON instead of JSONP, .done() works as expected. What am I doing wrong or need to change?
The problem is specified here:
ReferenceError: callback is not defined
Your JSONP response has callback hard-coded. That's incorrect. JSONP needs to set the function name dynamically.
When jQuery sends a JSONP request, it creates a function called jQuery123456 (or something like that) and sends that name in the request. It calls endpoint1?callback=jQuery123456. The job of JSONP is to make a call to that function. Your JSONP needs to return:
jQuery123456({
your: 'data'
})
You need to use the value of the callback parameter.
If for some reason, creating the JSONP "dynamically" isn't an option, you can force jQuery to name the callback function it creates. You need to use $.ajax for this:
$.ajax({
url: 'endpoint1',
dataType: 'jsonp',
jsonp: false, // Don't add the "?callback=?" param,
// you're not using it anyway
jsonpCallback: 'callback' // Force jQuery to use "callback"
// as the function name
});
Note: jQuery probably won't like having the same callback value for multiple requests.

How to ensure that the javascript is loaded only once

I am calling a JS using jquery getScript().
Sometimes i could see that the files are already loaded (cached resource).
So,On refreshing the cached page is not removed and also the same file is loaded again.
Because of the multiple includes of the same file i am getting errors.
How to avoid that ?
$.getScript("http://localhost:8888//../../demo.js", function()
{
console.log('Script is loaded.');
});
By default, $.getScript sets the cache setting to false. Try setting it to true to see if this solves your problem:
$.ajaxSetup({
cache: true
});
Add the above before your call like:
$.ajaxSetup({
cache: true
});
$.getScript("http://localhost:8888//../../demo.js", function() { console.log('Script is loaded.'); });
directly from jquery docs:
Caching Responses
By default, $.getScript() sets the cache setting to false. This
appends a timestamped query parameter to the request URL to ensure
that the browser downloads the script each time it is requested. You
can override this feature by setting the cache property globally using
$.ajaxSetup():
$.ajaxSetup({ cache: true }); Alternatively, you could define
a new method that uses the more flexible $.ajax() method.
Examples: Example: Define a $.cachedScript() method that allows
fetching a cached script:
jQuery.cachedScript =
function( url, options ) {
// Allow user to set any option except for dataType, cache, and url options = $.extend( options || {}, {
dataType: "script",
cache: true,
url: url });
// Use $.ajax() since it is more flexible than $.getScript // Return the jqXHR object so we can chain callbacks return
jQuery.ajax( options ); }; // Usage $.cachedScript( "ajax/test.js"
).done(function( script, textStatus ) { console.log( textStatus );
});
I believe if it is cached the browser will not go make a new request for it, it will know to load the cached version, so you are good just firing off your $.getScript as you have it.
It may appear in the network tab of chrome developer tools again, but the time will be 0 and the Size (Content) value will say '(from cache)' This would be a good way to test what is actually going on.
Assuming your demo.js file contains at least one function or variable, you could check for presence before loading again:
if (typeof(your_variable) === "undefined") {
$.getScript("http://localhost:8888//../../demo.js", function() { console.log('Script is loaded.'); });
}
(where your_variable is the name of a function or variable inside demo.js)
Cashingvis good feature I solved multiple time loading js when I I load through jquery before. My issue was when I call a file loading by jquery I have a jquery file in that loading file now it loads only once so then events i now envoje only once. Thanks a lot have a nice day.

JQuery to load Javascript file dynamically

I have a very large javascript file I would like to load only if the user clicks on a certain button. I am using jQuery as my framework. Is there a built-in method or plugin that will help me do this?
Some more detail:
I have a "Add Comment" button that should load the TinyMCE javascript file (I've boiled all the TinyMCE stuff down to a single JS file), then call tinyMCE.init(...).
I don't want to load this at the initial page load because not everyone will click "Add Comment".
I understand I can just do:
$("#addComment").click(function(e) { document.write("<script...") });
but is there a better/encapsulated way?
Yes, use getScript instead of document.write - it will even allow for a callback once the file loads.
You might want to check if TinyMCE is defined, though, before including it (for subsequent calls to 'Add Comment') so the code might look something like this:
$('#add_comment').click(function() {
if(typeof TinyMCE == "undefined") {
$.getScript('tinymce.js', function() {
TinyMCE.init();
});
}
});
Assuming you only have to call init on it once, that is. If not, you can figure it out from here :)
I realize I am a little late here, (5 years or so), but I think there is a better answer than the accepted one as follows:
$("#addComment").click(function() {
if(typeof TinyMCE === "undefined") {
$.ajax({
url: "tinymce.js",
dataType: "script",
cache: true,
success: function() {
TinyMCE.init();
}
});
}
});
The getScript() function actually prevents browser caching. If you run a trace you will see the script is loaded with a URL that includes a timestamp parameter:
http://www.yoursite.com/js/tinymce.js?_=1399055841840
If a user clicks the #addComment link multiple times, tinymce.js will be re-loaded from a differently timestampped URL. This defeats the purpose of browser caching.
===
Alternatively, in the getScript() documentation there is a some sample code that demonstrates how to enable caching by creating a custom cachedScript() function as follows:
jQuery.cachedScript = function( url, options ) {
// Allow user to set any option except for dataType, cache, and url
options = $.extend( options || {}, {
dataType: "script",
cache: true,
url: url
});
// Use $.ajax() since it is more flexible than $.getScript
// Return the jqXHR object so we can chain callbacks
return jQuery.ajax( options );
};
// Usage
$.cachedScript( "ajax/test.js" ).done(function( script, textStatus ) {
console.log( textStatus );
});
===
Or, if you want to disable caching globally, you can do so using ajaxSetup() as follows:
$.ajaxSetup({
cache: true
});

Categories