for loop not making multiple buttons correctly - javascript

So i'm trying to make multiple buttons with a for loop such as
const buttonSection = document.getElementById('listOfFiles');
for (let i = 0; i < arrayOfFiles.length; i++){
const questionnaireSelector = document.createElement('input');
questionnaireSelector.type = 'button';
questionnaireSelector.id = 'selectorButton' + i;
questionnaireSelector.value = arrayOfFiles[i];
buttonSection.appendChild(questionnaireSelector);
and instead of making a button for each element in the arrayOfFiles array which is populated earlier on in the code, it makes one button and instead just writes all of the contents of the array into the value of that one button.
Would anyone be able to help?
Thanks

I have added the necessary missing elements. You should replace them.
HTML:
<div id='listOfFiles'></div>
JS:
const buttonSection = document.getElementById('listOfFiles');
const arrayOfFiles = [1,2,3,4] // to be replaced
for (let i = 0; i < arrayOfFiles.length; i++){
const questionnaireSelector = document.createElement('input');
questionnaireSelector.type = 'button';
questionnaireSelector.id = 'selectorButton' + i;
questionnaireSelector.value = arrayOfFiles[i];
buttonSection.appendChild(questionnaireSelector);
}
see it in action

I figured it out, because the contents of the array are retrieved from the server in array form already, when i push it to arrayOfFiles it becomes a nested array. Which is why it only makes one button as it takes the index[0] of the encapsulating array. Full code :
"use strict";
const arrayOfFiles = [];
async function getListFromServer(){
const response = await fetch('/api/viewQuestionnaires');
const directory = await response.json();
arrayOfFiles.push(directory);
}
function displayListOfFiles(){
revealButton.remove();
const buttonSection = document.getElementById('listOfFiles');
for (let i = 0; i < arrayOfFiles.length; i++){
let questionnaireSelector = document.createElement('input');
questionnaireSelector.type = 'button';
questionnaireSelector.id = 'selectorButton' + i;
questionnaireSelector.value = arrayOfFiles[i];
buttonSection.appendChild(questionnaireSelector);
}
}

Related

Cannot push JSON elements to array inside for loop called from useEffect

I have an array candleRealTimeDataQueue which is not getting updated properly. Please find the code below:
let candleCurrentJSONDataWS = null;
var candleRealTimeDataQueue = [];
let tempDateTime = null;
let candleJsonData = {};
useEffect(() => {
getDataFromAPI();
}, []);
...
const getDataFromAPI = async () => {
let apiDataFetch = await fetch('https:/api/endpoint');
let response = await apiDataFetch.json(); // data from api obtained correctly
// total 4 values
for (var i = 0; i < 4; i++) {
tempDateTime = new Date(parseInt(response[i][0]));
candleJsonData['time'] = tempDateTime.toString();
candleJsonData['open'] = parseFloat(response[i][1]);
candleJsonData['high'] = parseFloat(response[i][2]);
candleJsonData['low'] = parseFloat(response[i][3]);
candleJsonData['close'] = parseFloat(response[i][4]);
console.log(candleJsonData); // this correctly prints different
// data for each different i
candleRealTimeDataQueue.push(candleJsonData);
console.log(candleRealTimeDataQueue); // PROBLEM is here: At the end
// candleRealTimeDataQueue array all
// have SAME elements. Its wrong. All
// 4 elements are of i = 3
}
}
Problem is at the end candleRealTimeDataQueue has 4 elements and all the elements are same. This should not happen because I am pushing DIFFERENT candleJsonData elements in the candleRealTimeDataQueue array in the for loop. Please help.
I believe the problem here is that you are reusing the candleJsonData object. When you run candleRealTimeDataQueue.push(candleJsonData), you are pushing the reference to candleJsonData into candleRealTimeDataQueue. So at the end of the loop, you have four references to the same object inside candleRealTimeDataQueue. And since you are modifying the same candleJsonData object over and over again, you'll just see four identical json data inside the queue when you log it and all four elements will be of i = 3.
Instead, you should be creating new candleJsonData objects inside your loop. So something like
for (var i = 0; i < 4; i++) {
tempDateTime = new Date(parseInt(response[i][0]));
let candleJsonData = {}
candleJsonData['time'] = tempDateTime.toString();
candleJsonData['open'] = parseFloat(response[i][1]);
candleJsonData['high'] = parseFloat(response[i][2]);
candleJsonData['low'] = parseFloat(response[i][3]);
candleJsonData['close'] = parseFloat(response[i][4]);
candleRealTimeDataQueue.push(candleJsonData);
}
it is because of the candleJsonData variable which is declared outside, so latest value is overriding previous value. In face there is no need of that variable and it can directly push in the array.
var candleRealTimeDataQueue = [];
React.useEffect(() => {
getDataFromAPI().then((data) => {
for (let i = 0; i < 4; i++) {
candleRealTimeDataQueue.push({
time: new Date(parseInt(data[i][0])).toString(),
open: parseFloat(data[i][1]),
low: parseFloat(data[i][3]),
close: parseFloat(data[i][4]),
});
}
});
return () => {
// do clean up here
};
}, []);
const getDataFromAPI = () => {
return fetch('https:/api/endpoint');
};

How to check value of innerText if is null

I am developing a web scrapping and I am trying to solve latest problems with this.
In this case I need to check if innerText is null inside loop.
for(var j = 0; j<linkPlayersNew.length;j++){
var stats = [];
for (let i = 2; i <= 23; i++) {
const values = await page.evaluate((nth,nth2) => {
const test= parseInt(nth);
const test2= parseInt(nth2);
return document.querySelector('div.ui-table__row:nth-child('+test2+') > div:nth-child('+test+')').innerText;
},i,j+1);
stats.push(values);
}
data.push(stats);
}
console.log(data);
This works correct but I need to check if innerText is not null inside loop.

Is there a way to store index of an array and get its value back?

here is the task: I am trying to build an anagram finder which receives a given string (simple word) from an input, then check in a dictionary (of 350k words) and then return all the anagrams of that word. Here is where I got so far:
const button = document.getElementById("findButton");
button.addEventListener("click", function() {
let typedText = document.getElementById("input").value;
let wordIn = typedText.toLowerCase().split("").sort().join("").trim();
let output = [];
for (let i = 0; i < dictionary.length; i++) {
if (dictionary[i].length === wordIn.length)
output.push(dictionary[i])
}
let sorted = [];
let result = [];
for (let i = 0; i < output.length; i++) {
sorted.push(output[i].toLowerCase().split("").sort().join("").trim())
if (wordIn === sorted[i]) {
result.push(sorted[i])
}
}
});
With the current approach I get as final output an array with words alphabeticaly sorted i.e.: cat ("act", "act", "act"...) , but I need them as they are in the dictionary. I was thinking if I could store the index of the words in the output array (which already reduces from 350k to only those with same length) and after temporary sort them by their alphabetic value, I could get only those which match and return them as a new array. i.e cat = "cat", "act", "tac".
You can use filter:
const
// Once, at the top of your script:
normalizeWord = w => w.toLowerCase().split("").sort().join("").trim(),
dictionary = ['foo', 'act', 'bar', 'cat', 'example', 'word'],
sortedDict = dictionary.map(normalizeWord),
// In your event handler, or its own named function:
wordIn = normalizeWord('tac'),
result = dictionary.filter((_, i) => sortedDict[i] === wordIn);
console.log(result);
You can first of all increase your performance by getting the desired result in the first loop itself, thus no requirement of extra array and extra loop saving space and time.
const button = document.getElementById("findButton");
button.addEventListener("click", function() {
let typedText = document.getElementById("input").value;
let wordIn = typedText.toLowerCase().split("").sort().join("").trim();
let output = []; //it will have your final anagram list
for (let i = 0; i < dictionary.length; i++) {
let sortedWord = dictionary[i].toLowerCase().split("").sort().join("").trim();
if (sortedWord === wordIn) {
output.push(dictionary[i]);
}
}
});
Instead of result.push(sorted[i])
You should result.push(output[i]) instead.

Javascript - Help retrieving data from Firebase

I have this code below to retrive data from firebase and turn into an array but whenever i call it it stops other functions from being called inside the code even tho I can perfectly call them in the console.
I've worked around this by using callback functions but I am at a point it just doesn't do anymore. How can make this part act like a normal function where I can call anytime without stopping the code.
function genList(){
dataRef.on('value', data => {
let arr = (data.val());
let keys = Object.keys(arr);
for (let i = 0; i < keys.length; i++) {
let k = keys[i];
let title = arr[k].title;
let author = arr[k].author;
let pages = arr[k].pages;
let date = arr[k].date;
let bookmark = arr[k].bookmark;
let newList = new Object();
newList.title = title;
newList.author = author;
newList.pages = pages;
newList.date = date;
newList.bookmark = bookmark;
bookList.push(newList);
}
})}

Adding dynamic named Javascript object to an array with a for loop

Wondering if it is possible to use a loop to add dynamically named objects to an array, so I don't need to repeat the "push" on an array. Tks !!
let _objA0 = { "name":"regionId", "value":"myRegion" };
let _objA1 = { "name":"vdcId", "value":"myId" };
let _objA2 ... _objA100
let test = []
test.push(_objA0)
test.push(_objA1)
...
test.push(_objA100)
I guess it's the right time to use eval
let test = [];
for(let i = 0; i <= 100; i++) {
test.push(eval(`_objA${i}`));
}
You can access variables (with var keyword) by window object , try this:
var _objA0 = { "name":"regionId", "value":"myRegion" };
var _objA1 = { "name":"vdcId", "value":"myId" };
let test = [];
for(let i = 0; i < 2; i++){
test.push(window['_objA' + i]);
}
console.log(test)

Categories

Resources