I'm trying to bring in data from an external json file, and use it to generate a table. I'm running into a problem on line 52 'Uncaught TypeError: Cannot convert undefined or null to object at Function.keys' . When I comment out the first 2 async functions, use the sample data in the 'mountains' variable and reference 'mountains' instead of users the html table generates as expected. I think the problem has to do with my 2nd async function but I'm a newbie at a loss. Any help appreciated!
async function getUsers() {
let url = '../assets/names.json';
try {
let res = await fetch(url);
return await res.json();
} catch (error) {
console.log(error)
}
}
async function users() {
let users = await getUsers()
}
/* 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" }
];
*/
function generateTableHead(table, data) {
let thead = table.createTHead();
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(users[0]);
generateTableHead(table, data);
generateTable(table, users);
Since fetch is asynchronous, you need to process the data only once fetch receives it
This should give you an idea
async function getUsers() {
let url = '../assets/names.json';
try {
let res = await fetch(url);
return res.json();
} catch (error) {
console.log(error);
}
}
async function fakeGetUsers() {
// fake delay
await new Promise(res => setTimeout(res, 1000));
// simulate return res.json();
return [{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"}];
}
async function users() {
const users = await fakeGetUsers();
// here you can use the data
function generateTableHead(table, data) {
let thead = table.createTHead();
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);
}
}
}
const table = document.querySelector("table");
const data = Object.keys(users[0]);
generateTableHead(table, data);
generateTable(table, users);
}
users();
<table></table>