JavaScript - Push objects within object to global array - javascript

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

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) {
.....
}

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 to extract single element line by line and store in an array in Javascript?

I've got a text file 'mytext.txt' with IPs and some text seperate by commas in different lines -
24.16.153.165:51413,abc
67.185.72.127:51413,xyz
69.247.183.46:63303,pqr
130.56.220.16:6881,def
I want to store the IPs in an array in JavaScript to plot them on a map. I found a way to do this by using a static array -
var map = new google.maps.Map(document.getElementById('map'), googleMap);
var infowindow = new google.maps.InfoWindow();
google.maps.event.addListener(infowindow, "closeclick", function() {
map.fitBounds(latlngbound);
map.panToBounds(latlngbound)
})
var ipArray = ["70.177.167.189", "123.135.107.115", "123.135.107.115", "123.135.107.115", "123.135.107.115", "122.182.6.19", "24.19.187.145", "24.19.187.145", "27.251.20.130", "27.251.20.130"];
ipArray.forEach((ip) => {
addIPMarker(ip);
})
} catch(e){
//handle error
}
Can someone tell me how to do it after extracting the IPs from the text file? It should be a fairly simple logic, but I'm not very familiar with JavaScript. Thanks!
This function works if you have a file on the server or another url.
function loadDoc() {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var myObj = this.responseText;
var data = myObj.split(/\n/g);
var data_ip = [];
for(item in data)
{
var ip = data[item].split(/,/g);
data_ip.push(ip[0]);
}
console.log(data_ip);
}
};
xmlhttp.open("GET", "file.txt", true);
xmlhttp.send();
}
And this was work with a locally stored file.
function readTextFile(file)
{
var rawFile = new XMLHttpRequest();
rawFile.open("GET", file, false);
rawFile.onreadystatechange = function ()
{
if(rawFile.readyState === 4)
{
if(rawFile.status === 200 || rawFile.status == 0)
{
var myObj = rawFile.responseText;
var data = myObj.split(/\n/g);
var data_ip = [];
for(item in data)
{
var ip = data[item].split(/,/g);
data_ip.push(ip[0]);
}
console.log(data_ip);
}
}
}
rawFile.send(null);
}
readTextFile("file:///C:/your/path/to/file.txt");
To read a file in from your system you need to use the fs (file system) module provided by Node. You won't need to do any npm install.
JavaScript file:
const fs = require('fs');
const mapData = fs.readFileSync(//path to file here);
// do things with the data like your ip mapping, etc...
I have used the fs.readFileSync() function in the example but you will want to read the documentation and see what works best for your application.
Documentation:
https://nodejs.org/api/fs.html

How to delay a method until another is finished first , javascript?

I'm currently working on a project for school using a pokemon api that will display the information needed to evolve the pokemon (please note that I'm completely new to javascript and HTML).
Link :http://pokeapi.co/docsv2/
The website will ask the user for a name and that name will be used to get a url for the main information that I'm looking for.
For example : if someone enters in pikachu, the program will request the object for pikachu which contains the url for pikachu's evolution chain and that url is the one that will provide the main information for the website.
Currently the code looks like this:
var pokemon = new XMLHttpRequest();
var name = prompt("Whats the name of the pokemon you have?").toLowerCase();
var url = "http://pokeapi.co/api/v2/pokemon-species/" + name;
var url2;
pokemon.onreadystatechange = function(){
if(pokemon.readyState == 4 && pokemon.status == 200){
var myArr = JSON.parse(pokemon.responseText);
var url2 = myArr.evolution_chain;
}
}
pokemon2.onreadystatechange = function() {
if (pokemon2.readyState == 4 && pokemon2.status == 200) {
var myArr2 = JSON.parse(pokemon2.responseText);
console.log(myArr2.chain.species.name);
}
}
var pokemon2 = new XMLHttpRequest();
pokemon2.open("GET", url2, true).done(onreadystatechange);
pokemon2.send();
pokemon.open("GET", url, true);
pokemon.send();
However the program doesn't work due to the fact that the getting is occurring at the same time and pokemon2 should only be called after pokemon is finished because it's getting the actual url for pokemon2.
Does anyone know how to be able to accomplish this?
Many thanks! :).
You can call pokemon2 once pokemon finishes:
pokemon.onreadystatechange = function(){
if(pokemon.readyState == 4 && pokemon.status == 200){
var myArr = JSON.parse(pokemon.responseText);
var url2 = myArr.evolution_chain;
// Call pokemon2 here
var pokemon2 = new XMLHttpRequest();
pokemon2.open("GET", url2, true);
pokemon2.send();
}
}

How to use Get to parse multiple JSON files?

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();
}}

Categories

Resources