Set variable from function with possible ajax-load inside? - javascript

I have made my own script for loading content with AJAX if nor already loaded. Here it is:
/*
* AJAX Load Content
*/
var loaded_content_urls = {};
function get_content_from_url(url)
{
if (loaded_content_urls[url] === undefined)
{
$.ajax({url: url}).done(function(data)
{
loaded_content_urls[url] = data;
return data;
});
}
else
{
return loaded_content_urls[url];
}
}
And I wanna use it like this:
var loaded_html = get_content_from_url($(this).attr('href') + '?ajax');
But that won't work great since it can take a while for the content to be loaded and the variable above needs the value directly. So how should I do this?
I did a search about the issue but only found solutions where you always loads the content with AJAX. My code is special in that way that it first checks if the content already have been loaded. So I can't just have the AJAX function as return of the function.

Try using https://api.jquery.com/deferred.promise/
Your example code should like below:
var urlData = ''
function get_content_from_url (url) {
var _defer = jQuery.Deferred();
if( urlData === undefined){
$.ajax({url: url}).done(function(data){
urlData = data;
_defer.resolve(urlData);
});
} else{
_defer.resolve(urlData);
}
return _defer.promise();
};
$.when(get_content_from_url(url)).then( function( data) {
var loaded_html = data;
});
I will also suggest to use reject and fail method to handle error scenarios

Related

Call a function within the .done of a Jquery.post call

I am confused on this one.
I am trying to call another defined function within the AJAX done and i get the function cannot be found error.
I have also tried to declare this as a variable and use that still get the same issue, cannot find the function.
var self = this
...
$.post.done(function(respose) {
self.init_customer_dropdown();
})
If i call the function outside of the AJAX request works fine
Here is the full code block
$('.save-client-modal').on('click', function(e) {
e.preventDefault();
//Save Cutomer to Database
var url = admin_url + "clients/create_client_ajax";
var data = {};
...
$.post(url, data).done(function (response){
response = JSON.parse(response);
if(response.success == true || response.success == "true")
{
init_customer_dropdown(); <-- will not run this function
}
else
{
alert_float('warning', response.message);
}
});
});
function init_customer_dropdown()
{
alert("Customer Dropdown");
}
Thanks in Advance
Mike

How to preload JSON link?

I've got a function that needs to call a link (JSON format), the fact is that I would like to be able to preload this link to smooth and reduce the operation time when calling the function.
onSelectionChanged: function (selectedItems) {
selectedItems.selectedRowsData.forEach(function(data) {
if(data) {
colorMe(data.target)
}
});
}
function colorMe(item){
globalItem = item;
request('http://blablabla/?format=json',findMaterial);
};
function findMaterial(data){
jq310.each(data, function(table) {
if (data[table].identifier == globalItem){
globalData = data[table]
request('http://another-blablabla/?format=json',findMatchArea);
};
});
};
function findMatchArea(areas){
jq310.each(areas, function(area) {
blablabla
The request function that I built just look if the link as been already called, so it's reloading it if true. And also send data from the link to the called function.
If you'r looking to load a static json file you should concider loading it on the top of your file. To do so you should store the datas in a global variable like that :
let datas;
request('http://blablabla/?format=json', (data) => {
datas = data
});
onSelectionChanged: function (selectedItems) {
selectedItems.selectedRowsData.forEach(function(data) {
if(data) {
globalItem = data.target;
findMaterial();
}
});
}
function colorMe(item){
globalItem = item;
};
function findMaterial(){
const data = datas;
jq310.each(data, function(table) {
if (data[table].identifier == globalItem){
globalData = data[table]
request('http://another-blablabla/?format=json',findMatchArea);
};
});
};
I finally found a way to do it properly, here it is :
var mylink = 'https://fr.wikipedia.org/wiki/JavaScript';
function preloadURL(link){
var xhReq = new XMLHttpRequest();
xhReq.open("GET", link, false);
xhReq.send(null);
var jsonObject = JSON.parse(xhReq.responseText);
return jsonObject;
};
jsonObjectInv = preloadURL(mylink);
And I just point to my json variable to parse it (really faster)
function colorMe(item){
globalItem = item;
findMaterial(jsonObjectInv);
};
Problem solved

Set Value from JSON via AJAX

I'm using Github Gists for a web playground I'm making as a side project. I load two json files into the editor. 1 handles all the libraries (jquery, bootstrap, etc:) and another for the users settings (fontsize, version, etc:)
So anyway I have this JSON named settings
var settings = gistdata.data.files["settings.json"].content
var jsonSets = JSON.parse(settings)
I parse and attempted to grab an object from the JSON and set it as a value of a input textbox.
Now console.log(jsonSets.siteTitle) works perfectly fine
but when I try to change the input dynamically...
$("[data-action=sitetitle]").val(jsonSets.siteTitle).trigger("change")
The problem is it's not actually applying the value!
The only way I've been able to successfully apply the value is...
setTimeout(function() {
$("[data-action=sitetitle]").val(jsonSets.siteTitle).trigger("change")
}, 5000)
Which is ridiculously slow.
Does anyone know why it's not applying the value?
in addition.
How can I solve this problem?
var hash = window.location.hash.substring(1)
if (window.location.hash) {
function loadgist(gistid) {
$.ajax({
url: "https://api.github.com/gists/" + gistid,
type: "GET",
dataType: "jsonp"
}).success(function(gistdata) {
var libraries = gistdata.data.files["libraries.json"].content
var settings = gistdata.data.files["settings.json"].content
var jsonLibs = JSON.parse(libraries)
var jsonSets = JSON.parse(settings)
// Return libraries from json
$.each(jsonLibs, function(name, value) {
$(".ldd-submenu #" + name).prop("checked", value)
})
// Return font settings from json
var siteTitle = jsonSets.siteTitle
var WeaveVersion = jsonSets.version
var editorFontSize = jsonSets.editorFontSize
var WeaveDesc = jsonSets.description
var WeaveAuthor = jsonSets.author
$("[data-action=sitetitle]").val(siteTitle).trigger("change")
$("[data-value=version]").val(WeaveVersion).trigger("change")
$("[data-editor=fontSize]").val(editorFontSize).trigger("change")
$("[data-action=sitedesc]").val(WeaveDesc).trigger("change")
$("[data-action=siteauthor]").val(WeaveAuthor).trigger("change")
}).error(function(e) {
// ajax error
console.warn("Error: Could not load weave!", e)
})
}
loadgist(hash)
} else {
// No hash found
}
My problem was actually related to localStorage.
I cleared it localStorage.clear(); ran the ajax function after and it solved the problem.
var hash = window.location.hash.substring(1)
if (window.location.hash) {
localStorage.clear()
function loadgist(gistid) {
$.ajax({
url: "https://api.github.com/gists/" + gistid,
type: "GET",
dataType: "jsonp",
jsonp: "callback"
}).success(function(gistdata) {
var htmlVal = gistdata.data.files["index.html"].content
var cssVal = gistdata.data.files["index.css"].content
var jsVal = gistdata.data.files["index.js"].content
var mdVal = gistdata.data.files["README.md"].content
var settings = gistdata.data.files["settings.json"].content
var libraries = gistdata.data.files["libraries.json"].content
var jsonSets = JSON.parse(settings)
var jsonLibs = JSON.parse(libraries)
// Return font settings from json
var siteTitle = jsonSets.siteTitle
var WeaveVersion = jsonSets.version
var editorFontSize = jsonSets.editorFontSize
var WeaveDesc = jsonSets.description
var WeaveAuthor = jsonSets.author
$("[data-action=sitetitle]").val(siteTitle)
$("[data-value=version]").val(WeaveVersion)
$("[data-editor=fontSize]").val(editorFontSize)
$("[data-action=sitedesc]").val(WeaveDesc)
$("[data-action=siteauthor]").val(WeaveAuthor)
storeValues()
// Return settings from the json
$(".metaboxes input.heading").trigger("keyup")
// Return libraries from json
$.each(jsonLibs, function(name, value) {
$(".ldd-submenu #" + name).prop("checked", value).trigger("keyup")
})
// Set checked libraries into preview
$("#jquery").trigger("keyup")
// Return the editor's values
mdEditor.setValue(mdVal)
htmlEditor.setValue(htmlVal)
cssEditor.setValue(cssVal)
jsEditor.setValue(jsVal)
}).error(function(e) {
// ajax error
console.warn("Error: Could not load weave!", e)
})
}
loadgist(hash)
} else {
// No hash found
}

Javascript variable scope hindering me

I cant seem to get this for the life of me. I cant access the variable "json" after I calll the getJson2 function. I get my json dynamically through a php script, and that works. But then its gone. there is a sample that I use as a guide at The InfoVis examples where the json is embedded in the init function. i am trying to get it there dynamically.
<script language="javascript" type="text/javascript">
var labelType, useGradients, nativeTextSupport,animate,json;
function getJson2()
{
var cd = getParameterByName("code");
$.get("tasks.php?code="+cd, function(data){
return data;
})
};
function getParameterByName(name)
{
name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
var regexS = "[\\?&]" + name + "=([^&#]*)";
var regex = new RegExp(regexS);
var results = regex.exec(window.location.search);
if(results == null)
return "";
else
return decodeURIComponent(results[1].replace(/\+/g, " "));
}
(function() {
var ua = navigator.userAgent,
iStuff = ua.match(/iPhone/i) || ua.match(/iPad/i),
typeOfCanvas = typeof HTMLCanvasElement,
nativeCanvasSupport = (typeOfCanvas == 'object' || typeOfCanvas == 'function'),
textSupport = nativeCanvasSupport
&& (typeof document.createElement('canvas').getContext('2d').fillText == 'function');
//I'm setting this based on the fact that ExCanvas provides text support for IE
//and that as of today iPhone/iPad current text support is lame
labelType = (!nativeCanvasSupport || (textSupport && !iStuff))? 'Native' : 'HTML';
nativeTextSupport = labelType == 'Native';
useGradients = nativeCanvasSupport;
animate = !(iStuff || !nativeCanvasSupport);
})();
debugger;
var Log = {
elem: false,
write: function(text){
if (!this.elem)
this.elem = document.getElementById('log');
this.elem.innerHTML = text;
debugger;
this.elem.style.left = (500 - this.elem.offsetWidth / 2) + 'px';
}
};
function init(){
json = getJson2();
//init data
var st = new $jit.ST({
//id of viz container element
injectInto: 'infovis',
//set duration for the animation
duration: 800,
//set animation transition type ..................
function getJson2()
{
var cd = getParameterByName("code");
$.get("tasks.php?code="+cd, function(data){
return data;
})
};
getJson2() doesn't return anything. The callback function to $.get() returns something, but nothing is listening for that return.
It sounds like you want synchronous loading instead. $.get() is just shorthand for this $.ajax() call: (See docs)
$.ajax({
url: url,
data: data,
success: success,
dataType: dataType
});
And $.ajax() supports more features, like setting async to false.
$.ajax({
url: "tasks.php?code="+cd,
async: false,
dataType: 'json',
success: function(data) {
// data !
}
});
Which means, getJson2 then becomes:
function getJson2()
{
var cd = getParameterByName("code");
var jsonData;
$.ajax({
url: "tasks.php?code="+cd,
async: false,
dataType: 'json',
success: function(data) {
jsonData = data;
}
});
return jsonData;
};
var myJsonData = getJson2();
Or still use $.get async style, and use callbacks instead.
function getJson2(callback)
{
var cd = getParameterByName("code");
$.get("tasks.php?code="+cd, function(data){
callback(data);
});
};
getJson2(function(data) {
// do stuff now that json data is loaded and ready
});
The $.get call is asynchronous. By the time you call return data;, the function has already long since returned. Create a variable outside of your function's scope, then in the $.get callback handler, assign data to that variable.
var json;
function getJson2(){
// ...
$.get(...., function(response){
json = response;
}
});
Alternatively, you could do a sychronous Ajax call, in which case returning your data would work (but of course would block script execution until the response was recieved). To accomplish this, see the asynch argument to jQuerys $.ajax function.
A jQuery $.get call is asynchronous and actually returns a promise, not the data itself.
An elegant way to deal with this is to use the then() method:
$.get(...).then(function(data){...});
Alternately, change your ajax settings to make the call synchronous.
$.get("tasks.php?code="+cd, function(data){
return data;
})
$.get is asynchroneous. So your value is never returned. You would have to create a callback.
The same question appears here:
Return $.get data in a function using jQuery

jquery passing array data to function

I have made a function to get the variable of onclick and pass it to the function, but I want it in different format:
$('.ajax').live('click', function() {
var Loading = 'Loading...';
var url = $(this).attr('href');
var container = '#myDivcontent';
looadContents(url,Loading,container);
return false;
});
and the function looks like :
looadContents(url,Loading,container) {
..
...
$(contaner).load(url);
...
..
}
I would like to have like array format or json data format when I call the function:
$('.ajax').live('click', function() {
looadContents({
url : $(this).attr('href'),
Loading : 'Loading...',
container: '#myDivcontent'
});
return false;
});
Any idea how can I do this?
If you pass the information like an object, you can simply access it as one:
function looadContents(options) {
$(options.container).load(options.url);
}
looadContents({ url: '...', container: '#...' });
This syntax works as expected.
function display(obj)
{
console.log(obj.name + " loves " + obj.love);
}
display({name:"Jared", love:"Jamie"});
Is this possibly what you are looking for?
function looadContents(o) {
alert(o.url);
alert(o.container);
}
looadContents({ url:"abc", container: "def" });
Use what's sometimes called an "options" object (what you refer to as "JSON data format" is simply a JavaScript object literal):
function loadContents(options) {
var url = options.url;
var Loading = options.Loading;
/* etc. */
}
You can also leverage this approach to provide default values for certain parameters:
function loadContents(options) {
var url = options.url || "http://default-url.com/",
var Loading = options.Loading || "Loading...";
var container = options.container || "#container";
$(container).load(url);
}
Try this
looadContents(input) {
//...
$(input.contaner).load(input.url);
//...
}

Categories

Resources