JS/Ajax/Jquery consecutive requests through linked list [duplicate] - javascript

This question already has answers here:
While looping a jquery ajax call
(3 answers)
Closed 1 year ago.
My code:
<script type="text/javascript">
var x = 1;
var data = JSON.parse( document.getElementById('json').innerHTML);
var next = data['next'];
var jsonData = data['data'];
while (next != null) {
x = x+1;
var nextFileUrl = data['next'];
console.log('next:', nextFileUrl);
const xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
data = this.response;
next = JSON.parse(this.response)['next'];
console.log('newNext:',next);
newJsonData = JSON.parse(this.response)['data'];
console.log('newJsonData:',newJsonData);
jsonData['data'].push(newJsonData);
}
});
xhr.open("GET", nextFileUrl);
xhr.send(null);
}
</script>
Data example:
{
"next" : "path2",
"data" : "some data here"
}
I have multiple JSON files described as above that I need to access consecutively, in a "while next != null" kind of loop, starting with the data that's already in the page. For every call, I need to get the data value, and do something with it, and then make the next call. Currently, my code seems to constantly be logging the result from the first response only.
I'm fairly new to javascript and ajax, and have no experience with jquery. I can't use fetch, as I need the solution to work for all browsers. I'm looking for the best solution to this between JS, Ajax and JQuery if someone can point me in the right direction.

Your sending async requests in a while loop and expecting a value to update each iteration, but that will never work since the loop will not wait for the request to complete. Rather than a loop, you can call a function recursively until the condition is satisfied
var x = 1;
var data = JSON.parse(document.getElementById('json').innerHTML);
var next = data['next'];
var jsonData = data['data'];
function cycle() {
if (!next) return;
x = x + 1;
var nextFileUrl = next;
console.log('next:', nextFileUrl);
const xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function() {
if (this.readyState === this.DONE) {
data = this.response;
next = JSON.parse(this.response)['next'];
console.log('newNext:', next);
newJsonData = JSON.parse(this.response)['data'];
console.log('newJsonData:', newJsonData);
jsonData['data'].push(newJsonData);
// call the function
if (next) cycle();
}
});
xhr.open("GET", nextFileUrl);
xhr.send(null);
}

Related

Can not make XMLHttpRequest to 3 separate API urls

Before I start, here is the API. Super simple: https://www.cryptonator.com/api
To note, I have worked with api before, but i used a await async function, but for some reason I couldn't get that to work....but I found a tutorial for doing this with XML http request, so I decided to just move forwards doing it in XML because I was able to make a simple Bitcoin ticker.
I am building a simple widget to display the prices of Bitcoin, Litecoin, and Ethereum using the cryptonator API. Like I said above, I made a bitcoin ticker with the first function ( see code below ), and it works great. However, I am having issues trying to get 3 different currencies.
Here is what I am trying to do.
var url = "https://api.cryptonator.com/api/ticker/btc-usd";
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var json = JSON.parse(this.responseText);
parseJson(json);
}
};
xmlhttp.open("GET", url, true);
xmlhttp.send();
function parseJson(json) {
var usdValue = json["ticker"]["price"];
document.getElementById("data").innerHTML = usdValue;
var usdValue = usdValue.replace(/[^\d.\-]/g, "");
var usd = parseFloat(usdValue);
document.getElementById("data").innerHTML = "$ " + usd.toFixed(2);
}
//
//
var xmlhttp2 = new XMLHttpRequest();
var url2 = "https://api.cryptonator.com/api/ticker/ltc-usd";
xmlhttp2.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var json = JSON.parse(this.responseText);
parseJson(json);
}
};
xmlhttp2.open("GET", url2, true);
xmlhttp2.send();
function parseJson(json) {
var LTCusdValue = json["ticker"]["price"];
// document.getElementById("data2").innerHTML = LTCusdValue;
var LTCusdValue = LTCusdValue.replace(/[^\d.\-]/g, "");
var LTCusd = parseFloat(LTCusdValue);
document.getElementById("data2").innerHTML = "$ " + LTCusd.toFixed(2);
}
//
//
//
var xmlhttp3 = new XMLHttpRequest();
var url3 = "https://api.cryptonator.com/api/ticker/eth-usd";
xmlhttp3.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var json = JSON.parse(this.responseText);
parseJson(json);
}
};
xmlhttp3.open("GET", url3, true);
xmlhttp3.send();
function parseJson(json) {
var ETHusdValue = json["ticker"]["price"];
// document.getElementById("data3").innerHTML = ETHusdValue;
var ETHusdValue = ETHusdValue.replace(/[^\d.\-]/g, "");
var ETHusd = parseFloat(ETHusdValue);
document.getElementById("data3").innerHTML = "$ " + ETHusd.toFixed(2);
}
As you can see, I am trying to make 3 request to 3 different APis, but it isn't working. If I comment out all but one of these functions, it works fine. My issues comes when i try to use all 3 at once. If i use Bitcoin and Litecoin only, it will actually work, but will just break again once I try to use the 3rd function ( to get ethereum price ).
The parseJson function is defined three times. This means that every time you write the function it will overwrite the previous definition. So in your case only the last parseJson function will be used for all three requests. You could do a couple of things.
Write three different variations. (Bad practice)
Though this would be the less favorable of the options. It will require you to have repeated code copied multiple times. This can be done more efficiently.
function parseJson1(json) {
...
}
function parseJson2(json) {
...
}
function parseJson3(json) {
...
}
Add an argument to the function. (Good practice)
Give the parseJson function a second argument that selects the element to output the value. This should be the id of the element you'll want to select.
This is the better solution because it only requires you to write a function once and call it multiple times accounting for the variations.
function parseJson(json, id) {
var output = document.getElementById(id); // Select the element based on the id.
if (output === null) { // If element is not found, stop the function.
return;
}
var price = json["ticker"]["price"];
var usdValue = price.replace(/[^\d.\-]/g, "");
var usd = parseFloat(usdValue);
output.innerHTML = "$ " + usd.toFixed(2);
}
The last technique is applicable to the rest of your code. Be aware of repeating yourself. You'll write much cleaner and better code when you only have to write something once.
If I understood you well you can create a method for all cryptos and avoid repeting the same code. If you run the example below you will be able to see all cryptos and also it's easy to add new ones:
const URL = 'https://api.cryptonator.com/api/ticker/'
const cryptos = ['btc', 'ltc', 'eth']
cryptos.map(crypto => {
fetch(`${URL}${crypto}-usd`)
.then(data => data.json())
.then(({ ticker: { base, price } }) => console.log(`${base}: ${(+price).toFixed(2)}`))
})
We are using fetch that is modern XHR. Hope this help.
You should be able to write an async wrapper function for this using a Promise.. This will allow you to use async/await with XHR..
To make using XHR a lot easier, you can use the built in fetch API.. According to this, most browsers support fetch.. All in all, I prefer using fetch over axios, XHR, etc.. but since you specifically asked about XHR, that is how I answered.
If you did not want to await each response, you can do something like this:
// basic XHR wrapper function for 'get'
function getXHR(url) {
return new Promise(function(resolve, reject) {
const xhr = new XMLHttpRequest();
xhr.open("get", url, true);
xhr.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
this.status == 200
? resolve(this.responseText)
: reject(this.status);
}
};
xhr.send();
});
}
const ethElement = document.getElementById("eth");
const bcElement = document.getElementById("bc");
const lcElement = document.getElementById("lc");
// etherium
getXHR("https://api.cryptonator.com/api/ticker/eth-usd")
.then(eth => {
// Can turn into JSON like this:
//const ethJson = JSON.parse(eth);
ethElement.innerHTML = eth;
})
// bitcoin
getXHR("https://api.cryptonator.com/api/ticker/btc-usd")
.then(bc => {
// Can turn into JSON like this:
//const bcJson = JSON.parse(bc);
bcElement.innerHTML = bc;
})
// litecoin
getXHR("https://api.cryptonator.com/api/ticker/ltc-usd")
.then(lc => {
// Can turn into JSON like this:
//const lcJson = JSON.parse(lc);
lcElement.innerHTML = lc;
})
<h1>eth:</h1>
<pre id="eth"></pre>
<h1>bc:</h1>
<pre id="bc"></pre>
<h1>litecoin:</h1>
<pre id="lc"></pre>
I have created the following demo to show you how to accomplish this using async/await:
Init(); // call 'main' function
// basic XHR wrapper function for 'get'
function getXHR(url) {
return new Promise(function(resolve, reject) {
const xhr = new XMLHttpRequest();
xhr.open("get", url, true);
xhr.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
this.status == 200
? resolve(this.responseText)
: reject(this.status);
}
};
xhr.send();
});
}
// "Main" function
async function Init() {
const ethElement = document.getElementById("eth");
const bcElement = document.getElementById("bc");
const lcElement = document.getElementById("lc");
// etherium
const eth = await getXHR("https://api.cryptonator.com/api/ticker/eth-usd");
const ethJson = JSON.parse(eth);
ethElement.innerHTML = ethJson.ticker.price + " " + ethJson.ticker.target;
// bitcoin
const bc = await getXHR("https://api.cryptonator.com/api/ticker/btc-usd");
const bcJson = JSON.parse(bc);
bcElement.innerHTML = bcJson.ticker.price + " " + bcJson.ticker.target;
// litecoin
const lc = await getXHR("https://api.cryptonator.com/api/ticker/ltc-usd");
const lcJson = JSON.parse(lc);
lcElement.innerHTML = lcJson.ticker.price + " " + lcJson.ticker.target;
}
div h1,
div p {
display: inline;
vertical-align: top;
font-family: 'Open Sans', sans-serif;
line-height: 38px;
}
<div>
<h1>eth:</h1>
<p id="eth"></p>
</div>
<div>
<h1>btc:</h1>
<p id="bc"></p>
</div>
<div>
<h1>ltc:</h1>
<p id="lc"></p>
</div>

How to transfere data from one function to another using javascript

Hey everybody I have a problem.
I am building a website and I want to fetch data from two different xml files with two different functions.
ShowResult is used to get a game score and the name of a specific user.
GiveFeedback also needs the score from the first function to fetch a fitting feedback about this score from a different xml file.
I don´t get an error Message. My only problem is that the second function (giveFeedback) isn´t able to fetch data from the xml because it needs a variable (score) from the first function (showResults). Both functions work on their own but I am unable to “transfer” the score data from showResults to giveFeedback.
How can I transfer the score data to the function GiveFeedback or is there a better way to resolve this problem?
Thanks!
i tried some solutions (global variable, inserting the first function in the second,..) which were already posted but unfortunately i didn´t managed to get it running.
<script>
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
showResult(xhttp.responseXML);
}
};
xhttp.open("GET", "user.xml", true);
xhttp.send();
function showResult(xml) {
var name = "";
var score = "";
path1 = "/userdb/user/name";
path2 = "/userdb/user/score";
var nodes = xml.evaluate(path1, xml, null, XPathResult.ANY_TYPE, null); var result = nodes.iterateNext();
name = result.childNodes[0].nodeValue;
var nodes = xml.evaluate(path2, xml, null, XPathResult.ANY_TYPE, null); var result = nodes.iterateNext();
//Thats wehere the variable (score) is, which i need for the second function (giveFeedback)
score = result.childNodes[0].nodeValue;
document.getElementById("user").innerHTML = "Congratulations " + name + ", you made " + score;
}
var xhttp2 = new XMLHttpRequest();
xhttp2.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
givefeedback(xhttp2.responseXML);
}
};
xhttp2.open("GET", "feedback.xml", true);
xhttp2.send();
function givefeedback(xml) {
var feedback = "";
// This is where it´s needed
if (score > 1){
path = "/feedback/congratulations[percentage=25]/text";
}
else if (score > 8){
path = "/feedback/congratulations[percentage=50]/text";
}
var nod = xml.evaluate(path, xml, null, XPathResult.ANY_TYPE, null);
var res = nod.iterateNext();
feedback = res.childNodes[0].nodeValue;
document.getElementById("feedback").innerHTML = feedback;
}
</script>
i managed to resolve my problem.
first of all i had to declare a global variable outside the functions.
Then i had to convert the fetched variable (score) to a Number.

Asynchronous Ajax Call Mixing Up Callbacks

So basically I have an ajax function pretty standard one. Like so:
function ajax_call(rest_req, url, success_callback, fail_callback) {
// if (request_in_progress)
// return;
// request_in_progress = true;
var xhttp = new XMLHttpRequest;
xhttp.onreadystatechange = function () {
if (this.readyState == 4) {
// request_in_progress = false;
if (this.status == 200) {
success_callback(this);
}
else {
fail_callback(this);
}
}
};
xhttp.open(rest_req, url, true);
xhttp.send();
}
When I use the ajax function this way:
(function() {
function setup() {
ajax_call("GET", "url1", function(xhttp) {
response = JSON.parse(xhttp.responseText);
if (response["error"] != 100)
document.getElementById('url1-reading').innerHTML = '---';
else
document.getElementById('url1-reading').innerText = response["response"];
},
function() {}
);
ajax_call("GET", "url2" , function(xhttp) {
response = JSON.parse(xhttp.responseText);
if (response["error"] != 100)
document.getElementById('url2-reading').innerHTML = '---';
else
document.getElementById('url2-reading').innerText = response["response"];
},
function() {}
);
console.log('Refresh');
}
setInterval(setup, 1000);
})();
This code behaves differently than what I expect. When I run this code, there are some times when the results that were suppose to go to url1 success_callback goes inside url2's success_callback.
To put another way the response variable inside url1 ajax_call is what I expected to show up as response variable for url2. So in effect the ajax_call seem to not know what success_callback is for what even though I explicitly pass it in as a parameter.
I'm coming from a C++ background so this is a difficult concept to grasp. How do I do this the right way? I hope my question is clear. Please tell me what is not clear so I can clarify.
The way you declare it, response is a global variable. Try changing response = to let response =

Adjacently Dependent AJAX (improved)

This question was posted a couple of days ago, but since I'm a nub it was filled with spaghetti code and that sort of thing (please pardon the form handling as well) That aside, I've added some notes and given some context, but the problem still lies in the second AJAX call.
This is the error that Chrome is throwing "Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource."
I have hidden the URL because it contains an API key that I would rather not share.
Any and all criticisms are warmly welcomed
/*
This module will take a user's name, return an ID
then search more stats in the api with the ID.
*/
var search = document.getElementById('search');
search.addEventListener('click', function(){
var demo = document.getElementById('demo');
var player_name = document.getElementById('player_name').value;
var player_id;
// Interpolated API URLs
var name_url = 'URL.pre'+player_name+'URL.end';
var stats_url; //nested in the second ajax call to pass updated player_id
// Get player ID
var xhr = new XMLHttpRequest();
var id_return_text;
xhr.onload = function(){
if(xhr.status === 200) {
id_return_text = JSON.parse(xhr.responseText);
player_id = id_return_text[player_name].id;
demo.innerHTML = id_return_text[player_name].name +', your player ID is: '+player_id;
}
};
xhr.open('GET', name_url, true);
xhr.send();
// Search stats with ID
var xhr_2 = new XMLHttpRequest();
var stats_return_text;
xhr.done = function(){
stats_url = "URL.pre"+player_id+"URL.end";
if(xhr_2.status == 200) {
stats_return_text = JSON.parse(xhr_2.responseText);
demo.innerHTML += stats_return_text['playerStatsSummaries'].playerStatType;
}
};
xhr_2.open("GET",stats_url, true);
xhr_2.send();
});
<div id="container">
<img id="duck" src="duck.png" alt="duck">
<div class="form_wrapper">
<h1 id="app_header">*QUACK* What's Your player ID?</h1>
<form>
<input
type="text"
id="player_name"
placeholder="Summoner Name">
<input type="button" id="search" value="Search">
</form>
</div>
<p id="demo"></p>
</div>
<script type="text/javascript" src="script.js"></script>
So your primary error was that if you need to make CORS requests (or any AJAX requests, really), you need to run the code from a server (even localhost).
Google (and most browsers) will freak out at you if your page's protocol is "file:///" and you're trying to load things from the internet (or vice versa). And "file:///" cannot make requests for other files, either.
Future reference: you also can't make "http" requests from an "https" page.
That out of the way, the second issue (the one that was being hidden by CORS security), is that your AJAX requests are being run in parallel right now.
In order to make this work the way you think it should (after the first one returns, run the second one), you would need to:
move all of the code at the bottom, relating to xhr_2 inside of the xhr.onload
move all of the code inside of xhr.done at the bottom inside of the xhr.onload and replace all of the duplicate information (and use the references to the returned results directly)
This results in something like:
var search = document.getElementById('search');
search.addEventListener('click', function(){
var demo = document.getElementById('demo');
var player_name = document.getElementById('player_name').value;
var player_id;
// Interpolated API URLs
var name_url = 'https://na.api.pvp.net/api/lol/na/v1.4/summoner/by-name/'+player_name+'?api_key=<THIS IS THE API KEY>';
var stats_url; //nested in the second ajax call to pass updated player_id
// Get player ID
var xhr = new XMLHttpRequest();
var id_return_text;
xhr.onload = function(){
if(xhr.status === 200) {
id_return_text = JSON.parse(xhr.responseText);
player_id = id_return_text[player_name].id;
demo.innerHTML = id_return_text[player_name].name +', your player ID is: '+player_id;
// Dropped the XHR_2 stuff here
var xhr_2 = new XMLHttpRequest();
var stats_return_text;
stats_url = "https://na.api.pvp.net/api/lol/na/v1.3/stats/by-summoner/"+player_id+"/summary?season=SEASON2016&api_key=<THIS IS THE API KEY>";
// CHANGED THIS TO BE XHR_2.onload -- IN HERE I KNOW XHR_1 IS ALREADY FINISHED
xhr_2.onload = function(){
if(xhr_2.status == 200) {
stats_return_text = JSON.parse(xhr_2.responseText);
demo.innerHTML += stats_return_text['playerStatsSummaries'].playerStatType;
}
};
xhr_2.open("GET",stats_url, true);
xhr_2.send();
}
};
xhr.open('GET', name_url, true);
xhr.send();
});
That should solve practically all of your woes.
The point of this is that onload is a callback which gets fired long after the program has been run, but xhr_2 was firing immediately after you requested data for xhr_1 (not after it was returning the data).
As such, player_id was undefined.
We want to wait until after we know we have player_id, and we know we have it (or some error) when we're inside the callback to xhr_1.onload.
This gets terribly confusing and very nested, and while I think that Promises and Async Functions / Generators are brilliant solutions for managing that complexity, that's way beyond the scope of this; so instead, I'd suggest looking at some functional composition, to simplify all of this:
function noop () { } // do nothing
function getJSON (url, onload, onerror) {
var xhr = new XMLHttpRequest();
onload = onload || noop; // what I've been given or nothing
onerror = onerror || noop; // " "
xhr.onload = function () {
var data;
var error;
try {
// it's possible for parse to throw on malformed JSON
data = JSON.parse(xhr.responseText);
} catch (e) {
error = e;
}
return error ? onerror(error) : onload(data); // fire one or the other (don't fall into the handler, if onload throws)
};
xhr.onerror = onerror;
xhr.open("GET", url);
xhr.send();
}
// localize URL construction
function buildPlayerIdUrl (name) { return "https://______" + name + "_____"; }
function buildPlayerStatsUrl (id) { return "https://______" + id + "_____"; }
// gets player by name and runs a function after the player has been loaded
function getPlayer (player_name, done, error) {
var id_url = buildPlayerIdUrl(player_name);
function buildPlayer (response) {
var player = response[player_name];
return player;
}
function onload (response) {
done(buildPlayer(response));
}
// Load the JSON, build the player, pass the player to done()
getJSON(url, onload, error);
}
// get stats by player id and runs a function after the stats have been loaded
function getPlayerStats (player_id, done, error) {
var stats_url = buildPlayerStatsUrl(player_id);
function buildStats (response) {
var summary = response.playerStatsSummaries;
return summary;
}
function onload (response) {
done(buildStats(response));
}
// Load the JSON, build the stats, pass the stats to done()
getJSON(stats_url, onload, error);
}
// perform a search by player name
// note: All changes in step-number (1, 2, 3) are asynchronous,
// and thus, must be nested in callbacks of some sort
function search (player_name) {
// Step 1: load the player
getPlayer(playerName, function (player) {
// Step 2a: update the DOM with the player name/id
updatePlayerDom(player);
// Step 2b: load the player stats
getPlayerStats(player.id, function (stats) {
// Step 3: update the DOM with the stats
updateStatsDom(stats);
});
});
}
// player DOM update; keeping it nice and simple
function updatePlayerDom (player) {
document.querySelector(".Player-id").textContent = player.id;
document.querySelector(".Player-name").textContent = player.name;
}
// stats DOM update; same as above
function updateStatsDom (stats) {
document.querySelector(".Player-stats").textContent = stats.playerStatType;
}
// bootstrap yourself to your UI
some_button.onclick = function () {
var player_name = some_input.value;
search(player_name); // kick the whole thing off
};
It's definitely more code, but it's also simpler to make edits to each individual piece, without stepping on the toes of other pieces.
It's (hopefully) also easier to see the _eventual timeline_ of all of the pieces, and how they flow, inside of the search( ) itself.

Issue with for-loop and standard Javascript AJAX

I have some issues with a for-loop and AJAX. I need to fetch some information from a database, so I pass the incrementing variable to PHP to grab the information and then send it back. The trouble is that it skips immediately to the maximum value, making it impossible to store any of the information.
I would prefer not to use jQuery. It may be more powerful, but I find Javascript easier to understand.
Here is the JS code:
for (var i = 0; i <= 3; i++) {
var js_var = i;
document.getElementById("link").onclick = function () {
// ajax start
var xhr;
if (window.XMLHttpRequest) xhr = new XMLHttpRequest(); // all browsers
else xhr = new ActiveXObject("Microsoft.XMLHTTP"); // for IE
var url = 'process.php?js_var=' + js_var;
xhr.open('GET', url, false);
xhr.onreadystatechange = function () {
if (xhr.readyState===4 && xhr.status===200) {
var div = document.getElementById('test1');
div.innerHTML = xhr.responseText;
if (js_var == 2) {
var rawr = document.getElementById('test2');
rawr.innerHTML = xhr.responseText;
}
}
}
xhr.send();
// ajax stop
return false;
}
};
Here is the PHP code:
<?php
if (isset($_GET['js_var'])) $count = $_GET['js_var'];
else $count = "<br />js_var is not set!";
$con = mysql_connect("xxx","xxxxx","xxxx");
mysql_select_db('computerparty_d', $con);
$get_hs = mysql_query("SELECT * FROM hearthstone");
$spiller_navn = utf8_encode(mysql_result($get_hs,$count,1));
echo "$spiller_navn";
?>
what you actually are doing is binding an onclick event in your for-loop not sending ajax request, and the other point is, it immediately overrides the previous onclick handler which you have created in the previous iteration.
So if you want to add multiple listeners you should first consider using nested functions and closures to keep the i variable safe for each listener, and then use addEventListener instead of setting the onclick function. Considering these points you can do this instead:
for (var i = 0; i <= 3; i++) {
var clickFunc = (function (js_var) {
return function () {
// ajax start
var xhr;
if (window.XMLHttpRequest) xhr = new XMLHttpRequest(); // all browsers
else xhr = new ActiveXObject("Microsoft.XMLHTTP"); // for IE
var url = 'process.php?js_var=' + js_var;
xhr.open('GET', url, false);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
var div = document.getElementById('test1');
div.innerHTML = xhr.responseText;
if (js_var == 2) {
var rawr = document.getElementById('test2');
rawr.innerHTML = xhr.responseText;
}
}
}
xhr.send();
// ajax stop
return false;
};
})(i);
document.getElementById("link").addEventListener("click", clickFunc);
}
Be aware that you're making an synchronous AJAX call, which is undesirable (it hangs the browser during the request, which might not end). You may have problems in some browsers with this because you're calling onreadystatechange, that shouldn't be used with synchronous requests.
It looks like you are making the AJAX request with a user click.
for (var i = 0; i <= 3; i++) {
var js_var = i;
document.getElementById("link").onclick
When this JS is executed it will override the "onclick" listener of "link" twice. First time it is assigned for the first time, second time it is overwritten, and the third time it is overwritten again. The result is that when the "link" element is clicked only the last listener exists, resulting in making a single AJAX request for the last configuration.
HTTP request are expensive(time), it might be worth to get all of the data in one request and then use client-side JS to sift through that data accordingly.
jQuery is not more powerful than JS, it is JS with a bunch of wrapper functions. My personal opinion is that once IE9 is no longer relevant, jQuery will be only used by people who know jQuery and not JS.

Categories