I am trying to pass information from an API call into an HTML table which I can then also use for graphs. A picture of the array is attached to show the data structure. I keep receiving an error that column_names is not iterable but I have not been able to work it out after hours of searching. I think it has to do with the names in my array but can't find a solution. I'm new to this and I feel like the answer is painfully simple so any help or explanation of my error would be appreciated.
Array Format
async function loadintotable(url, table) {
const tableHead = table.querySelector('thead');
const tableBody = table.querySelector('tbody');
const response = await fetch(url);
const { column_names, data } = await response.json();
tableHead.innerHTML = '<tr></tr>';
tableBody.innerHTML = '';
for (const headerText of column_names) {
const headerElement = document.createElement('th');
headerElement.textContent = headerText;
tableHead.querySelector('tr').appendChild(headerElement);
}
for (const row of data) {
const rowElement = document.createElement('tr');
for (const cellText of row) {
const cellElement = document.createElement('td');
cellElement.textContent = cellText;
rowElement.appendChild(cellElement);
}
tableBody.appendChild(rowElement);
}
}
Your api response is of format
{
dataset: {
column_names: [],
data: []
}
}
So, in order to access column_names and data you have to
const json = await response.json();
const { column_names, data } = json.dataset;
Or in one line
const { column_names, data } = (await response.json()).dataset;
Notice the .dataset at the end of the line
Related
We are trying to retrieve data from a nested parent child relationship from realtime database from firebase using javascript (Html). Below is the code we are using and output, but the section of where there is nested data we are getting [object, Object] and undefined. We get the desired output on the console but not on the webpage.
const db = getDatabase();
var tablebody = document.getElementById('assQuestions');
var asspool = [];
function addassquesvalues(quescat,quesid,queslaws,lawname,statements,question){
let trow=document.createElement('tr');
let td1=document.createElement('td');
let td2=document.createElement('td');
let td3=document.createElement('td');
let td4=document.createElement('td');
let td5=document.createElement('td');
let td6=document.createElement('td');
asspool.push(quescat,question,queslaws);
td1.innerHTML = quescat;
td2.innerHTML = quesid;
td3.innerHTML = queslaws;
td4.innerHTML = lawname;
td5.innerHTML = statements;
td6.innerHTML = question;
trow.appendChild(td1);
trow.appendChild(td2);
trow.appendChild(td3);
trow.appendChild(td4);
trow.appendChild(td5);
trow.appendChild(td6);
tablebody.appendChild(trow);
console.log(queslaws)
}
function addassquesvaluestotable(questions){
tablebody.innerHTML="";
questions.forEach(element=>{
addassquesvalues(element.quescat, element.quesid, element.queslaws, element.lawname, element.statements, element.question);
})
}
function getdatarealtime(){
const dbref=ref(db,"AssessmentQues");
onValue(dbref,(snapshot)=>{
var allassques = [];
snapshot.forEach(childSnapshot => {
allassques.push(childSnapshot.val());
});
addassquesvaluestotable(allassques);
})
}
window.onload = getdatarealtime;
Output in form of a table
I'm learning JavaScript and trying to master what should be a basic process, fetching data from a .json file and outputting it to an HTML Table.
No problem when I uncomment the first 7 lines of code and comment out the next 3 lines that use 'fetch' . However when I try to 'fetch' and output the data from another file I get the error that I've indicated at line #39 (let data = Object.keys(mountains[0]. I checked the console.log and the 'names.json' file is there as expected so the problem is not with a file path or with the fetch request. I think my problem is at line 39 with the 'Object.keys function. I'm at a loss as to how to reference the json data that was fetched. Any help appreciated!
/*let mountains = [
{ name: "Monte Falco", height: 1658, place: "Parco Foreste Casentinesi" },
{ name: "Monte Falterona", height: 1654, place: "Parco Foreste Casentinesi" },
{ name: "Poggio Scali", height: 1520, place: "Parco Foreste Casentinesi" },
{ name: "Pratomagno", height: 1592, place: "Parco Foreste Casentinesi" },
{ name: "Monte Amiata", height: 1738, place: "Siena" }
]; */
(fetch("names.json")
.then(res => res.json()
.then(json => console.log(json))))
function generateTableHead(table, data) {
let thead = table.createHead();
let row = thead.insertRow();
for (let key of data) {
let th = document.createElement("th");
let text = document.createTextNode(key);
th.appendChild(text);
row.appendChild(th);
}
}
function generateTable(table, data) {
for (let element of data) {
let row = table.insertRow();
for (key in element) {
let cell = row.insertCell();
let text = document.createTextNode(element[key]);
cell.appendChild(text);
}
}
}
let table = document.querySelector("table");
let data = Object.keys(mountains[0]); //****************************** Uncaught ReferenceError: mountains is not defined
generateTable(table, mountains); // generate the table first
generateTableHead(table, data); // then the head
You can try something like this:
fetch("names.json")
.then(res => res.json())
.then(json => {
console.log(json)
// you need to get mountains from json
// if json is in the shape that is needed then leave as it is
const mountains = json
let table = document.querySelector("table");
let data = Object.keys(mountains[0]);
generateTable(table, mountains); // generate the table first
generateTableHead(table, data); // then the head
})
When you comment first 7 lines of code so the mountains variable becomes undefined as it is not created yet.
So to run this code you can do your stuff inside the second callback of fetch function i.e. when you get the data in json format, like:
function generateTableHead(table, data) {
let thead = table.createHead();
let row = thead.insertRow();
for (let key of data) {
let th = document.createElement("th");
let text = document.createTextNode(key);
th.appendChild(text);
row.appendChild(th);
}
}
function generateTable(table, data) {
for (let element of data) {
let row = table.insertRow();
for (key in element) {
let cell = row.insertCell();
let text = document.createTextNode(element[key]);
cell.appendChild(text);
}
}
}
fetch("names.json")
.then(res => res.json())
.then(json => {
let mountains = json;
let table = document.querySelector("table");
let data = Object.keys(mountains[0]);
generateTable(table, mountains); // generate the table first
generateTableHead(table, data); // then the head
})
I have a simple program that reads a css file (which is available on GitHub pages) and parse the css to an array so I can put at in a list.
I have an dictionary with words, like a vocabulary list which shows me the translation and I can also search for words.
Everything works fine so far but I am really new and this is my first project and I want some advise about my codestructure.
At the moment I have to fetch the csv file (which never changes) in different methods with getData. I do this in init dictionary and again in search and show, because I need the dictionary again. Wouldn’t it be better to get the data once and then use it with all functions?
But then I have to write a lot function into another which is not so good practice I think.
I would really appreciate some advise or link or topics/ direction I have to research, because I can’t find an answer about how to structure this well.
I just use html, css and js without any framework or library.
initDictionary();
async function initDictionary(){
//get data
const dictionary = await getData();
//fill html list with words
fillList(dictionary);
}
//show translation and info when click on word
show = async function (i){
let dictionary = await getData();
document.getElementById("word-text").innerHTML = dictionary[i].Wort;
document.getElementById("info").innerHTML = dictionary[i].Notizen;
}
//search stuff
search = async function() {
let dictionary = await getData();
let query = document.getElementById('search').value;
console.log(query);
if (query == ""){
return;
}
//init found to false
let found = -1;
for(let i=0; i< dictionary.length; i++){
if(query == dictionary[i].Übersetzung){
found = i;
break;
}else {
document.getElementById("word-text").innerHTML = "word not found";
document.getElementById("info").innerHTML ="";
}
}
if ( found >= 0){
show (found);
query = document.getElementById('search').value="";
}
}
//Start search when u press enter
let input = document.getElementById("search");
input.addEventListener("keyup", function(event) {
console.log(event);
if (event.key=== "Enter") {
search();
}
});
// get data
async function getData(){
const csv = await fetch('https://aboutwhite.github.io/data/data.csv');
let scvText = await csv.text();
let dictionary = csvToArray(scvText);
return dictionary;
}
// fill html list with words
function fillList(dictionary){
for(let i=0; i< dictionary.length; i++){
document.getElementById('word-list').innerHTML += "<li onclick='show("+i+")'>" + dictionary[i].Übersetzung+"</li>";
}
}
//parse csv to array
function csvToArray(str){
let delimiter = ","
const headers = str.slice(0, str.indexOf("\n")).split(delimiter);
const rows = str.slice(str.indexOf("\n") + 1).split("\n");
const arr = rows.map(function (row) {
const values = row.split(delimiter);
const el = headers.reduce(function (object, header, index) {
object[header] = values[index];
return object;
}, {});
return el;
});
return arr;
}
I am currently using fetch in javascript to obtain information from another site into my own. The issue I am having is, I am using a loop to display all of the indexes of the JSON file into my site. I actually want to get specific indexes to show, not all of them, for example, index 2,4 and 6.
Here is my code so far:
window.addEventListener("load", (event)=>{
const requestURL = 'https://byui-cit230.github.io/weather/data/towndata.json';
fetch(requestURL)
.then(function (response) {
return response.json();
})
.then(function (jsonObject) {
const towns = jsonObject['towns'];
for (let i = 0; i < towns.length; i++ ) {
let towninfo = document.createElement('section');
let townname = document.createElement('h2');
townname.textContent = towns[i].name;
towninfo.appendChild(townname);
document.querySelector('div.weathertowns').appendChild(towninfo);
}
});
})
This displays all of the towns in reference, but I only want to display the title of 3 specific ones. Any suggestions on how to proceed with this?
something like that
window.addEventListener("load", (event)=>
{
const requestURL = 'https://byui-cit230.github.io/weather/data/towndata.json'
, divWeathertowns = document.querySelector('div.weathertowns')
;
fetch(requestURL)
.then( response=>response.json() )
.then( jsonObject=>
{
const towns = jsonObject['towns']
;
for ( let i of [2,4,6] )
{
let towninfo = document.createElement('section')
, townname = document.createElement('h2')
;
townname.textContent = towns[i].name;
towninfo.appendChild(townname);
divWeathertowns.appendChild(towninfo);
}
});
})
<div class="weathertowns"></div>
I am using an API from Caspio to import a Data Table that will be variable.
for that, I am doing the following
<script type="text/javascript" id='Test' src="https://c1afw487.caspio.com/dp/6e444000877ca58e63624b0b8c78/emb"></script>
and then to format it (send it to the bottom of my web page) I am doing this:
<div id='InfoTable' style='width: 40%; float: left;'>
<a id='TestTwo' href="https://c1afw487.caspio.com/dp/6e444000877ca58e63624b0b8c78">DataTable </a>
</div>
Now, I am trying to access the data from the table. For that I am trying something like this
var DataTest = document.getElementById('Test');
var DataTestTwo = document.getElementById('TestTwo');
console.log(JSON.stringify(DataTest));
console.log(JSON.stringify(DataTestTwo));
But the first test returns { } and the second one null (notice how I tried to give an ID to the imported table so I could access it but any of my attempts worked).
What is the proper way to access the Table?
I dont know anything about that specific API but quick google seems to suggest that they have a separate rest api for requesting JSON data. You should look into that.
Stringifying an html element does nothing usefull...its an html element not your request payload data.
You can go over the table itself and extract all the contents into a json.
Something like this.
https://jsfiddle.net/rainerpl/wvdoek03/14/
var getHeaders = (table) => {
const headerRow = table.tBodies[0].children[0];
const headers = [];
let i;
for (i = 0; i < headerRow.children.length; i++) {
headers.push(headerRow.children[i].innerText);
}
return headers;
}
var getData = (table) => {
const data = [];
let i;
for (i = 1; i < table.tBodies[0].children.length; i++) {
let newDataRow = [];
for (j = 0; j < table.tBodies[0].children[i].children.length; j++) {
newDataRow.push(table.tBodies[0].children[i].children[j].innerText);
}
data.push(newDataRow);
}
return data;
}
JsonTable = function() {
const table = document.getElementsByTagName('table')[0];
const headers = getHeaders(table);
const data = getData(table);
this.getRow = (rowNr) => {
const result = {};
headers.forEach((key, index) => {
result[key] = data[rowNr][index];
});
return result;
}
console.log('table', table, 'has data:', data, ' and headers ', headers);
}
const jsonTable = new JsonTable();
console.log('First row is', jsonTable.getRow(0));
console.log('Second row is', jsonTable.getRow(1));
You can view the console output on jsFiddle to see what it looks like.
( use inspect developer tool to see console output )