How to use Get to parse multiple JSON files? - javascript

I'm having some trouble parsing more than one JSON file at a time.
Basically, I have a web form with checkboxes that control which polygons to draw on a Google Map.
Depending what the user selects, that determines which JSON files (and geo coordinates) to get and parse. The script below works except for the last step - it always only returns the very last JSON file regardless how many are selected.
This is my first post to Stackoverflow and I'm new to JS, so any suggestions or different ways to approach this problem would be appreciated!
var xmlhttp = new XMLHttpRequest(); //
xmlhttp.onreadystatechange = function() { //parse json file
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var myArr = JSON.parse(xmlhttp.responseText);
console.log(myArr);
}
}
function goCheck() {
var input = document.getElementsByTagName('input');
var checkboxCount = 0;
var selections = [];
var urlArray = [];
for (var i=0, length = input.length; i<length; i++) {
if (input[i].checked === true) {
j = input[i].value;
selections.push(j); // store values for checkbox selections in array
checkboxCount++; // keep track how many were checked
var url = "https://mywebsite.ca/" + j + ".txt";
urlArray.push(url); // store urls in array
}
}
console.log(checkboxCount); // number of boxes checked
console.log(selections); // array with the selection values
console.log(urlArray); // an array with the json urls
// 2nd Loop - iterate over URL array and call function to get json object
for (var i=0, length = urlArray.length; i<length; i++) {
console.log(urlArray[i]);// check that loop is working
xmlhttp.open("GET", urlArray[i], true);
xmlhttp.send();
}}

You are reassigning what xmlhttp is doing each time. Create a new var each time and assign the state change handler to it and it should work. E.g.
for (var i=0, length = urlArray.length; i<length; i++) {
console.log(urlArray[i]);// check that loop is working
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() { //parse json file
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var myArr = JSON.parse(xmlhttp.responseText);
console.log(myArr);
}
};
xmlhttp.open("GET", urlArray[i], true);
xmlhttp.send();
}}
When you recall open on the same XMLHttpRequest you are abandoning the last request, but if you create a new one each time, they will each handle their own requests.
Aside, if you have control over the server side, a server method that takes in an array of files to get and returns a json array in a single AJAX call seems like the way to go long term.

You need to have a new XMLHttpRequest for each file. Replace your last loop with:
var xmlhttp;
for (var i=0, length = urlArray.length; i<length; i++) {
xmlhttp = new XMLHttpRequest(); //
xmlhttp.onreadystatechange = function() { //parse json file
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var myArr = JSON.parse(xmlhttp.responseText);
console.log(myArr);
}
}
console.log(urlArray[i]);// check that loop is working
xmlhttp.open("GET", urlArray[i], true);
xmlhttp.send();
}}

Related

JS: problem with for loop (only one image is shown)

I am completely new to javascript and web development.
I'm having a problem with the for loop; what happens to me is that the ids come back to me all together and not individually in order to retrieve the relative image and title through the id, so I can't recover images and title from the json array.
Specifically I get the error:
Uncaught TypeError: Cannot read properties of undefined (reading 'immagine') at XMLHttpRequest.xmlhttp.onreadystatechange
Warning: I have no problems in how to retrieve items in a json array because I know how to do it very well
This is my code:
//here I get all the articles, so my json array
var xmlhttp = new XMLHttpRequest();
var url = "https://wjko5u1234.execute-api.us-east-2.amazonaws.com/articles";
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var allart = JSON.parse(this.responseText);
var container=document.getElementById("slideshow")
for(var i = 0; i < allart.Items.length; i++)
{
container.innerHTML += '<div class="slideshow-container"></div>';
document.getElementById("id").innerHTML += "<br/>" + allart.Items[i].id;
myFunction1(allart.Items[i].id);
}
}
};
xmlhttp.open("GET", url, true);
xmlhttp.send();
//here I pass the id via function call, and for each id I want to retrieve image and title which has that specific id only i get the set of ids without having one at a time to retrieve what i need
function myFunction1(id) {
var xmlhttp = new XMLHttpRequest();
var url = "https://wjko5u1234.execute-api.us-east-2.amazonaws.com/articles/"+id;
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var myArr = JSON.parse(this.responseText);
console.log(myArr);
document.getElementById("img1").src="articoli_img/"+myArr.Item.immagine;
document.getElementById("title1").innerHTML = myArr.Item.titolo;
}
};
xmlhttp.open("GET", url, true);
xmlhttp.send();
}
I would be very thankful for any help.
It seems that "Item" prop doesn't exist in returned object (located in myFunction1()) (did you mean to write myArr.immagine?)
Since you are new: I recommend to use for-each loops in collections, by using:
for(let item of allart.Items) {
.....
}

JavaScript - Push objects within object to global array

ORIGINAL QUESTION
I'm trying to write a function in JavaScript that allows for articles from another source to be loaded on another page using an XMLHTTPRequest.
Each article is a JavaScript object containing the link, image, summary etc.
Each request will retrieve 5 articles, but I only want to show 4 articles on each button click. Because of this, I want to push the articles (objects) to a global array.
Since I'm fairly new at using XMLHTTPRequests, I can't find how to do this.
Everything works except for:
var i;
for (i = 0; i < newArticles.length; i++) {
articles.push(newArticles[i]);
}
newArticles is an object containing the 5 articles (objects) which I'm trying to push to the global array titled articles.
My code:
var articles = [];
document.getElementById("fc-blog-button-loadmore").addEventListener("click", receiveNewArticles);
function receiveNewArticles() {
var http = new XMLHttpRequest();
var url = "thelinktothepagewith5newarticles.json";
http.onreadystatechange = function() {
if(http.readyState == 4 && http.status == 200) {
var newObj = JSON.parse(http.responseText);
var newArticles = (newObj.blog.articles);
console.log(newObj);
console.log(newArticles);
var i;
for (i = 0; i < newArticles.length; i++) {
articles.push(newArticles[i]);
}
console.log(articles);
}
}
http.open("GET", url, true);
http.send();
}
SOLVED
After the helpful comments my code currently looks like this:
var articles = [];
document.getElementById("fc-blog-button-loadmore").addEventListener("click", receiveNewArticles);
function receiveNewArticles() {
var http = new XMLHttpRequest();
var url = "http://freshcotton-dev.webshopapp.com/nl/blogs/blog/page2.html?format=json";
http.onreadystatechange = function() {
if(http.readyState == 4 && http.status == 200) {
var newObj = JSON.parse(http.responseText);
var newArticles = (newObj.blog.articles);
console.log(newObj);
console.log(newArticles);
articles.push(...Object.values(newArticles))
console.log(articles);
}
}
http.open("GET", url, true);
http.send();
}
Problem has been solved!
You can solve the issue simply by using [spread operator][1] ...
articles.push(...Object.values(newArticles));
[1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax

How to Load CSV to array with object names

I want to be able to store the the data in my CSV files so I can read it easier and serve it to a webpage.
The CSV is in the following format, probname1:"meat1", probename2:"meat2".......
If I paste the data in manual like https://www.w3schools.com/js/tryit.asp?filename=tryjs_array_object
it works,
I also tried setting up my array dirrentely and using MGot90's method from Read CSV headers using Javascript
But I can only ever call 1 full value of each object e.g settings[0], and not call the object by its name e.g settings["ProbeName1"]
I want the following to beable to output meat1 with the following in the CSV file.
updatevalues.csv = probname1:"meat1", probename2:"meat2"
loadData();
function loadData() {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
parseCSV(this.responseText);
}
};
xmlhttp.open("GET", "js/updatevalues.csv", true);
xmlhttp.send();
}
function parseCSV(string) {
var allTextLines = string;
var settings = [];
var settings = allTextLines.split(",");
document.getElementById("demo1").innerHTML = settings["ProbeName1"];
}`
currently I can only get id=demo1 to output ProbeName1:"meat1" using settings[0].
If I use settings["ProbeName1"] it will display undefined.
This function will convert your csv into a JSON object:
function parseCSV(str) {
var allTextLines = str;
var settings = [];
var settings = allTextLines.split(",");
var results = {};
var name, val, idx;
for (var i = 0; i < settings.length; i++) {
idx = settings[i].indexOf(':');
name = settings[i].substring(0, idx);
val = settings[i].substring(idx+2, settings[i].length-1);
results[name] = val;
}
return results;
}
Working in fiddle: https://jsfiddle.net/p3t7Lv28/
That code strips the quotes off the values by using idx+2, length-1
Why you need that i dont know but may be you can use SheetJS tool.Its for showing the excel on the web.

How can I iterate through a function with for loop?

I want to pass the 'y' variable to okayid but there seems to be a problem with the looping. The loop works fine with the first call of 'y' on okay.item(y) but it is not looping through okayid.item(y). It seemed to me like it was a scope problem but I am not sure.
var okay = document.getElementsByClassName("Okay");
var okayid = document.getElementsByClassName("OkayID");
var numberOkays = okay.length;
for(y = 0; y <= numberOkays; y++){
okay.item(y).onclick = function(){
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function(){
if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
alert('vote Sent to picture with id = ' + okayid.item(y).innerHTML);
}
};
xmlhttp.open("GET", "ajax/vote.php", true);
xmlhttp.send();
};
}
Here is the html ...
<a class="Link1A Okay" href="#"><span class="OkayID">[id]</span><div class="Vote1A">Okay</div></a>
You've got lots if issues.
in the for loop, you don't init y with var which could cause problems, as now y is part of the global scope.
in the for loop, you have y <= numberOkays which will cause an empty element to be retrieved at the end since numberOkays is the result of the array's length. So you'd get okay[y] is undefined at the end.
You don't need to retrieve the okays at the onset, you can just get the appropriate element in the onclick event.
After the loops are done y will be at the last index, so when the click event is fired you'd always get the last element when you refer to the Okay[y] (or in your case you'll just get undefined because of problem 2). Using this will refer to the element clicked which effectively what you intended with Okay[y].
Here's an updated version of your code, with a link to a working jsFiddle below:
var okay = document.getElementsByClassName("Okay");
for(var y = 0; y < okay.length; y++){
okay[y].onclick = function(){
idElem = this.getElementsByClassName("OkayID")[0];
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function(){
if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
alert('vote Sent to picture with id = ' + idElem.innerHTML);
}
};
xmlhttp.open("GET", "ajax/vote.php", true);
xmlhttp.send();
};
}
jsFiddle

Why old red value persist in the browser, using XMLHttp request object?

I am reading a comma separated text file from the server, i get the valuse but when i chage the comma seprated variables in the file, it doesn't load the correct result int the browser
while browser persist the first time variable list only, whlile it works correct in IE, in firefox i am facig this proble.
How to sort it out
var arrUserTags = new Array();
var txt;
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "/TinyEditor/TextFile.txt", true);
xmlhttp.send();
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
txt = xmlhttp.responseText;
arrUserTags = txt.split(",");
alert(arrUserTags.length);
parse();
}
}
// Add some values to the list box
function parse() {
for (i = 0; i < arrUserTags.length; i++) {
mlb.add(arrUserTags[i], arrUserTags[i]);
alert('hi');
}
}
You server is presumably sending caching instructions that tell browsers the URI for the text file won't change for a while.
Either configure the server to send no cache headers, or change the URI (e.g. by adding a rand() query string to it).

Categories

Resources