How do I convert this code block into a Javascript loop? - javascript

This function operates perfectly, onclick it subtracts a price amount from 7 ‘cosT’ divs and 1 ‘cosT1’ div, as if removing an item from a shopping cart.
function changePrice0000() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var x = document.querySelectorAll(".cosT, .cosT1");
x[0].innerHTML = parseFloat(Number(x[0].innerHTML) - Number(x[7].innerHTML)).toFixed(2);
x[1].innerHTML = parseFloat(Number(x[1].innerHTML) - Number(x[7].innerHTML)).toFixed(2);
x[2].innerHTML = parseFloat(Number(x[2].innerHTML) - Number(x[7].innerHTML)).toFixed(2);
x[3].innerHTML = parseFloat(Number(x[3].innerHTML) - Number(x[7].innerHTML)).toFixed(2);
x[4].innerHTML = parseFloat(Number(x[4].innerHTML) - Number(x[7].innerHTML)).toFixed(2);
x[5].innerHTML = parseFloat(Number(x[5].innerHTML) - Number(x[7].innerHTML)).toFixed(2);
x[6].innerHTML = parseFloat(Number(x[6].innerHTML) - Number(x[7].innerHTML)).toFixed(2);
x[7].innerHTML = parseFloat(Number(x[7].innerHTML) - Number(x[7].innerHTML)).toFixed(2);
}
};
xhttp.open("GET", "text/p0000.txt", true);
xhttp.send();
}
I’ve tried a few variations of the following, nooby attempts at looping and getting it to work but without even remote success…
function changePrice0000() {
for(i=0; i<7; i++) {
var xhttp = new XMLHttpRequest();xhttp.onreadystatechange = function() {if (this.readyState == 4 && this.status == 200) {
var x = document.querySelectorAll(".cosT, .cosT1");
x[n].innerHTML = parseFloat(Number(x[n].innerHTML) - Number(x[7].innerHTML)).toFixed(2);
x[0].innerHTML = parseFloat(Number(x[0].innerHTML) - Number(x[7].innerHTML)).toFixed(2);}};
xhttp.open("GET", "text/p0000.txt", true);
xhttp.send();
}
}
…way beyond my capabilities , one for the experts I think, explicit assistance or just a point in the right direction would be most gratefully appreciated.

You were close, you only need the for loop around the part of the code you want to repeat. You also used an undefined variable n instead of the i in the loop, as #Rup mentioned in the comments:
function changePrice0000() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var x = document.querySelectorAll(".cosT, .cosT1");
for(i = 0; i<7; i++) {
x[i].innerHTML = parseFloat(Number(x[i].innerHTML) - Number(x[7].innerHTML)).toFixed(2);
}
xhttp.open("GET", "text/p0000.txt", true);
xhttp.send();
}
}
}

Here a small snippet with a simple loop solution:
var x = document.querySelectorAll(".cost");
x.forEach(function(el) {
el.innerHTML = parseFloat(Number(el.innerHTML) - Number(x[7].innerHTML)).toFixed(2);
});
<div class="cost">1</div>
<div class="cost">2</div>
<div class="cost">3</div>
<div class="cost">4</div>
<div class="cost">5</div>
<div class="cost">6</div>
<div class="cost">7</div>
<div class="cost">8</div>

function changePrice0000() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
var x = document.querySelectorAll(".cosT, .cosT1");
// loop over n starts here
for (n = 0; n < 7; n++) {
x[n].innerHTML = parseFloat(
Number(x[n].innerHTML) - Number(x[7].innerHTML)
).toFixed(2);
}
// loop ends here
}
xhttp.open("GET", "text/p0000.txt", true);
xhttp.send();
};
}
maybe this is what you mean? N is the var, so I from your example will not work, and you gotta makes sure your loop is inside of where you want to handle it...

Ok so huge thank you to the blisteringly fast expert responses, bit of jigging about–here is what is working perfectly (don’t ask me how :), endeavoured to indent a bit:
function changePrice0000() {var xhttp = new XMLHttpRequest();xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var x = document.querySelectorAll(".cosT, .cosT1");
// loop begins
for(n=0; n<7; n++) {
x[n].innerHTML = parseFloat(Number(x[n].innerHTML) - Number(x[7].innerHTML)).toFixed(2)};
// loop ends
x[n].innerHTML = parseFloat(Number(x[n].innerHTML) - Number(x[7].innerHTML)).toFixed(2);}};
xhttp.open("GET", "text/p0000.txt", true);
xhttp.send();}
Thanks again guys !!!

You just have to put for loop to the code which you want to repeat.
var n=7
for(i = 0; i <= n; i++) {
x[i].innerHTML = parseFloat(Number(x[i].innerHTML)-(Number(x[n].innerHTML)).toFixed(2);
}

Related

Because I only see the last element of the for loop

I'm having a problem; I have the following program code:
var xmlhttp = new XMLHttpRequest();
var url = "https://wjko5k6250.execute-api.us-east-2.amazonaws.com/motorcycle";
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var allmot = JSON.parse(this.responseText);
console.log(allmot);
for(var i = 0, len = allmot.Items.length; i < len; i++)
{
id=allmot.Items[i].id
var url1 = "https://wjko5k6250.execute-api.us-east-2.amazonaws.com/motorcycle/"+id;
console.log(url1);
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var myArr = JSON.parse(this.responseText);
console.log(myArr);
document.getElementById("img").src = myArr.Item.image;
document.getElementById("brd").innerHTML = myArr.Item.brand;
}
};
xmlhttp.open("GET", url1, true);
xmlhttp.send();
}
}
};
xmlhttp.open("GET", url, true);
xmlhttp.send();
allmot is as follows:
Items: Array (4)
0: {brand: 'Guzzi', id: '123456', image: 'moto_guzzi.jpg', date: '27/11/2021 '}
1: {brand: 'Bimota', id: '135623', image: 'bimota.jpg', date: '04/12/2021 '}
2: {brand: 'Ducati', id: '123789', image: 'b_desertx.jpg', date: ' 04/12/2021 '}
3: {brand: 'Benelli', id:' 146975 ', image:' benelli.jpg ', date: '27/11/2021'}
url1 returns (according to the for loop):
https://wjko5k6250.execute-api.us-east-2.amazonaws.com/articles/123456
https://wjko5k6250.execute-api.us-east-2.amazonaws.com/articles/135623
https://wjko5k6250.execute-api.us-east-2.amazonaws.com/articles/123789
https://wjko5k6250.execute-api.us-east-2.amazonaws.com/articles/146975
and so far everything seems to be fine.
The problem is in myArr; I noticed that it returns the image and brand of the last element only, so the one that has id equal to 146975.
Therefore there seems to be problems with the for loop.
Can anyone kindly help me? Thank you all.
As first correction I'd not recycle the XHR object from the outer loop in the inner loop.
When you say xmlhttp.onreadystatechange = function() ... in the inner loop, the xmlhttp is already in the readystate, obtained in the outer loop.
So, without further checking what is going on, I'd use two XHR objects (maybe like outerXmlhttp and innerXmlhttp). I'd also recreate the inner XHR for every cycle with:
var innerXmlhttp;
at the top of the outer closure.
Then, inside the cycle do:
innerXmlhttp = new XMLHttpRequest();
This is because of variable hoisting. If you just do this:
var innerXmlhttp = new XMLHttpRequest();
inside the cycle you may get a different behaviour. Just don't do it and write what you mean (hoist variables and assign them where you actually need it).
If all of this isn't enough ask a new, more precise question about what is going on.
This is your code with the corrections:
var outerXmlhttp = new XMLHttpRequest();
var url = "https://wjko5k6250.execute-api.us-east-2.amazonaws.com/motorcycle";
outerXmlhttp.onreadystatechange = function() {
var innerXmlhttp;
if (this.readyState == 4 && this.status == 200) {
var allmot = JSON.parse(this.responseText);
console.log(allmot);
for(var i = 0, len = allmot.Items.length; i < len; i++)
{
id=allmot.Items[i].id
var url1 = "https://wjko5k6250.execute-api.us-east-2.amazonaws.com/motorcycle/"+id;
console.log(url1);
innerXmlhttp = new XMLHttpRequest();
innerXmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var myArr = JSON.parse(this.responseText);
console.log(myArr);
document.getElementById("img").src = myArr.Item.image;
document.getElementById("brd").innerHTML = myArr.Item.brand;
}
};
innerXmlhttp.open("GET", url1, true);
innerXmlhttp.send();
}
}
};
outerXmlhttp.open("GET", url, true);
outerXmlhttp.send();
EDIT: #Teemu's eagle eye
As #Teemu points out in his comment, if you reassign values over and over to the same DOM objects like this:
document.getElementById("img").src = myArr.Item.image;
document.getElementById("brd").innerHTML = myArr.Item.brand;
you're clearly overwriting whatever value was there before. Instead, you should create and append those DOM objects, more like this:
var img = document.createElement("img");
img.src = myArr.Item.image;
var brd = document.createElement("p");
brd.innerText = myArr.Item.brand;
document.getElementById("motlist").append(img);
document.getElementById("motlist").append(brd);
Obviously, you'll need a <div id="motlist"></div> element or some other parent in the DOM to which to append the new elements.
For paging you may also want to clear those elements in the list... but here we're going overboard.

How do I write a sum function for text in HTML and text retrieved from an HTTP GET request's response?

I’m probably going about this the wrong way as I can’t find anything even close to what I’m trying to do, if anyone can point me in the right direction I would be grateful.
I have a button in my html to trigger a function ‘p0000’…
<button onclick="p0000();“>ADD</button>
Function:
function p0000() {var xhttp = new XMLHttpRequest();xhttp.onreadystatechange = function() {if (this.readyState == 4 && this.status == 200) {
var x = document.querySelectorAll(".cosT");
x[0].innerHTML = this.responseText;
x[1].innerHTML = this.responseText;
x[2].innerHTML = this.responseText;
x[3].innerHTML = this.responseText;
x[4].innerHTML = this.responseText;
x[5].innerHTML = this.responseText;
x[6].innerHTML = this.responseText;}};
xhttp.open("GET", "text/p0000.txt", true);
xhttp.send();}
The ‘text/p0000.txt’ document contains a price:
19.99
The function works perfectly, updates 7 instances of the ‘cosT’ divs with the new price of 19.99.
What I would like the function to do is ADD 19.99 to the amount already in the ‘cosT’ divs, NOT just replace the amount. Starting from 0.00, click once–see 19.99, click twice–see 39.98, and so on, so guessing I need to run another function within this function but no clue where to start.
Clearly, I have no clue how to loop over instances of ‘x’ either :)
Many thanks in advance.
Hi Sid, it’s part of a nav system so there’s seven variations of the following between the body tags, ‘cosT’ in the span tags:
<body>
<div id="detCapNav" class="sidenav">
<div class="cT"><div class="bT">BASKET TOTAL</div> <div class="bA">$<span class="cosT">0.00</span></div></div>
<div class="cT"><button class="coBtn bS" onclick="vBask();">VIEW BASKET</button></div>
<div class="cT"><button class="coBtn cS" onclick="closedetCapNav()">CONTINUE SHOPPING</button></div>
<div class="cT"><button class="coBtn pS" onclick="cHcol(this, 'rgba(250, 254, 231,1)');cartAdCapNav();p0000();">ADD TO BASKET</button></div>
<div class="tN"><img src="sample/image/01.jpg"></div>
<div class="iT"><div class="menuTitle">Baseball Cap</div></div>
</div>
So tried Sid’s solution:
let addedValue = parseFloat(document.getElementsByClassName("cosT")[0].textContent) + 10.90 document.getElementsByClassName("cosT")[0].innerHTML = addedValue.toFixed(2);
…which is great client-side, can’t see how to code it in with an http request, to get the value from the remote text file?
So, thank you Heretic:
function pageNew0000() {var xhttp = new XMLHttpRequest();xhttp.onreadystatechange = function() {if (this.readyState == 4 && this.status == 200) {
var x = document.querySelectorAll(".lead0");
x[0].innerHTML = this.responseText;}};
xhttp.open("GET", "text/pageNew0000.txt", true);
xhttp.send();}
function p0000() {var xhttp = new XMLHttpRequest();xhttp.onreadystatechange = function() {if (this.readyState == 4 && this.status == 200) {
var x = document.querySelectorAll(".cosT");
x[0].innerHTML = Number(x[0].innerHTML) + Number(this.responseText);
x[1].innerHTML = Number(x[1].innerHTML) + Number(this.responseText);
x[2].innerHTML = Number(x[2].innerHTML) + Number(this.responseText);
x[3].innerHTML = Number(x[3].innerHTML) + Number(this.responseText);
x[4].innerHTML = Number(x[4].innerHTML) + Number(this.responseText);
x[5].innerHTML = Number(x[5].innerHTML) + Number(this.responseText);
x[6].innerHTML = Number(x[6].innerHTML) + Number(this.responseText);}};
xhttp.open("GET", "text/p0000.txt", true);
xhttp.send();}
…added in your solution to each line, and it works perfectly, thanks again. If I could tidy this up with a loop, to loop all instances of ‘cosT‘, job done, any suggestions very welcome.
Well, you could sum them with parseFloat.
x[0].innerHTML = this.responseText + parseFloat(document.getElementsByClassName("cosT")[0].textContent);
Working fiddle: https://jsfiddle.net/6jpdtyuh/1/
Thanks to the rapid responses from Heretic and Sid I got two solutions to keep in my resources, both work perfectly, I opted for Heretic’s solution for my project–for no better reason than it looks ‘simpler’ to me.
function pageNew0000() {var xhttp = new XMLHttpRequest();xhttp.onreadystatechange = function() {if (this.readyState == 4 && this.status == 200) {
var x = document.querySelectorAll(".lead0");
x[0].innerHTML = this.responseText;}};
xhttp.open("GET", "text/pageNew0000.txt", true);
xhttp.send();}
function p0000() {var xhttp = new XMLHttpRequest();xhttp.onreadystatechange = function() {if (this.readyState == 4 && this.status == 200) {
var x = document.querySelectorAll(".cosT");
x[0].innerHTML = Number(x[0].innerHTML) + Number(this.responseText);
x[1].innerHTML = Number(x[1].innerHTML) + Number(this.responseText);
x[2].innerHTML = Number(x[2].innerHTML) + Number(this.responseText);
x[3].innerHTML = Number(x[3].innerHTML) + Number(this.responseText);
x[4].innerHTML = Number(x[4].innerHTML) + Number(this.responseText);
x[5].innerHTML = Number(x[5].innerHTML) + Number(this.responseText);
x[6].innerHTML = Number(x[6].innerHTML) + Number(this.responseText);}};
xhttp.open("GET", "text/p0000.txt", true);
xhttp.send();}
EDIT: For anyone that might be following up in the future, had an issue with the above function when the onClick was activated 5 times, the decimal places went to 14 or so, so added in ‘parseFloat’ & ‘.toFixed(2)’ as below, which fixed the problem.
function p0000() {var xhttp = new XMLHttpRequest();xhttp.onreadystatechange = function() {if (this.readyState == 4 && this.status == 200) {
var x = document.querySelectorAll(".cosT");
x[0].innerHTML = parseFloat(Number(x[0].innerHTML) + Number(this.responseText)).toFixed(2);
x[1].innerHTML = parseFloat(Number(x[1].innerHTML) + Number(this.responseText)).toFixed(2);
x[2].innerHTML = parseFloat(Number(x[2].innerHTML) + Number(this.responseText)).toFixed(2);
x[3].innerHTML = parseFloat(Number(x[3].innerHTML) + Number(this.responseText)).toFixed(2);
x[4].innerHTML = parseFloat(Number(x[4].innerHTML) + Number(this.responseText)).toFixed(2);
x[5].innerHTML = parseFloat(Number(x[5].innerHTML) + Number(this.responseText)).toFixed(2);
x[6].innerHTML = parseFloat(Number(x[6].innerHTML) + Number(this.responseText)).toFixed(2);}};
xhttp.open("GET", "text/p0000.txt", true);
xhttp.send();}

How do I get certain a property value from multiple objects using json?

I'm using this site:
https://jsonplaceholder.typicode.com/users/
as ajax practice with javascript.
I'm trying to get a certain property value from multiple IDs.
Let's use phone for example.
How can I loop through all the files and get every id and his phone?
Like this:
id : 1
phone : 123
id : 2
phone : 124
I'm trying to use for...in but I can't really get the hang of it rather than looping through only 1 of them.
function callToServer(param) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
//if (this.readyState == (4) Done && this.status == (200) All good) {
if (this.readyState == 4 && this.status == 200) {
res = JSON.parse(this.responseText);
for (var key in res) {
demo.innerHTML += `${key} : ${res[key]}<br>`;
}
}
}
// notice that I used "9" after to loop only through 1 :)
xhttp.open("GET", "https://jsonplaceholder.typicode.com/users/9", true);
xhttp.send();
}
Loop over the array and get the id and phone properties of each element. You can use forEach() for this rather than a for loop. See Why is using "for...in" for array iteration a bad idea?
function callToServer() {
let xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
let html = '';
let res = JSON.parse(this.responseText);
res.forEach(user => demo.innerHTML +=
html += `id ${user.id}: phone ${user.phone}<br>`;
)
demo.innerHTML = html;
}
}
xhttp.open("GET", "https://jsonplaceholder.typicode.com/users", true);
xhttp.send();
}
Access your data using res[key].id
function callToServer(param) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
res = JSON.parse(this.responseText);
for (var key in res) {
demo.innerHTML += `${key} : ${res[key].id}<br>`;
}
}
}

How to split the content of xmlhttp.response in javascript

i did manage to build a code that works and it does the splitting when added manually:
var input = '10;11;15;16';
var arr = input.split(';');
// update the content of the div with ID "humid"
document.getElementById('humid').textContent = arr[0];
document.getElementById('humid').style.width = `${arr[0]}%`;
document.getElementById('temp').textContent = arr[1];
document.getElementById('temp').style.width = `${arr[1]}%`;
document.getElementById('uv').textContent = arr[2];
document.getElementById('uv').style.width = `${arr[2]}%`;
document.getElementById('info').textContent = arr[3];
document.getElementById('info').style.width = `${arr[3]}%`;
the problem i have is that i want to use the data from this XMLHttpRequest,
this is how i get my value:
function readForestall() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("ForestAll").innerHTML =
this.responseText;
}
};
xhttp.open("GET", "readFORESTALL", false);
xhttp.send();
}
setInterval(function() {
readForestall();
}, 5000);
i did try a lot of things with no result, like this:
var input = 'ForestAll';
or input = document.getElementById('ForestAll').value
regards

(beginner javascript) get multiple text files xml request

Very grateful if someone can help me out with the syntax here- I am hoping to make several XML requests, each time getting a different text file. Here is the general structure of my code. How can I get each file in turn (f0, f1 and f2)?
window.onload = function(){
var f = (function(){
var xhr = [];
for (i = 0; i < 3; i++){
(function (i){
xhr[i] = new XMLHttpRequest();
f0 = "0.txt"
f1 = "1.txt"
f2 = "2.txt"
//??? xhr[i].open("GET", file i, true);
xhr[i].onreadystatechange = function () {
if (xhr[i].readyState == 4 && xhr[i].status == 200) {
//do stuff
}
};
xhr[i].send();
})(i);
}
})();
};
Simply put your filenames in an array.
window.onload = function(){
var f = (function(){
var xhr = [];
var files = ["f0.txt", "f1.txt", "f2.txt"];
for (i = 0; i < 3; i++){
(function (i){
xhr[i] = new XMLHttpRequest();
xhr[i].open("GET", files[i], true);
xhr[i].onreadystatechange = function () {
if (xhr[i].readyState == 4 && xhr[i].status == 200) {
//do stuff
}
};
xhr[i].send();
})(i);
}
})();
};
Something like this should work
// ...
for (i = 0; i < 3; i++){
(function (i){
xhr[i] = new XMLHttpRequest();
xhr[i].open('GET', i.toString() + '.txt'); // <-- this line
xhr[i].onreadystatechange = function () {
if (xhr[i].readyState == 4 && xhr[i].status == 200) {
// ....

Categories

Resources