do I have a question?
Can we connect two APIs on the same JavaScript page and retrieve the data from both APIs in the same table?
I want to connect two APIs and display the results of both APIs in the same table. The API is the same, only the Token changes.
Here is the code in JS
function csvJSON(csv) {
const lines = csv.split('\n');
const result = [];
const headers = lines[0].split(',');
for (let i = 1; i < lines.length; i++) {
if (!lines[i]) continue;
const obj = {};
const currentline = lines[i].split(',');
for (let j = 0; j < headers.length; j++) {
obj[headers[j]] = currentline[j];
}
result.push(obj);
}
return result;
}
function boutonSubmit(){
bounceType = document.getElementById('BouncesType').value;
datestart = document.getElementById('dateS').value;
dateend = document.getElementById('dateE').value;
//bounceCode = getElementById('#dateS').value;
// TOTAL BOUNCES
// Récupération des donnèes et convertion
fetch(`https://api7.esv2.com/v2/Api/Bounces?apiKey=867xxxxxxxGN&startDate=${this.datestart}&endDate=${this.dateend}&bounceType=${this.bounceType}`)
.then((response) => response.text())
.then((txtResponse) => {
const data = csvJSON(txtResponse);
const tbody = document.querySelector('#user-table tbody');
tbody.innerHTML = '';
data.forEach( (user) => {
const entry = document.createElement('tr')
entry.innerHTML = `
<tr>
<td class="column1">${user.Date}</td>
<td class="column2">${user.Email}</td>
<td class="column3">${user.BounceCode}</td>
<td class="column3">${user["BounceType "]}</td>
</tr>
`;
tbody.appendChild(entry);
});
})}
Thank you in advance.
Related
I am trying to build a table, where first cell is an image , next cells have some values, for which header is defined in thead.
The issue is that, in javascript, for every iteration of loop, it adds a new row, though I have not used <tr>
fetch("./static/js/data.json")
.then(response => response.json())
.then(data => {
for (var j = 0; j < 10; j++) {
let imgsrc = data.data[j].image;
document.querySelector("#userdata").innerHTML +=
`<tr><td rowspan="8"><img src=${imgsrc} width="150" height="150"></td>`;
for (var i = 0; i < 5; i++) {
let vmovieID = data.data[j].ingredients[i].contents;
document.querySelector("#userdata").innerHTML += `<td>${vmovieID}</td>`;
}
}
document.querySelector("#userdata").innerHTML += '</tr>'
});
<div class="panel-body">
<table id="userdata">
<thead>
<th>Image</th>
<th>Dry Matter</th>
<th>CP</th>
<th>GE</th>
<th>Calcium</th>
</thead>
</table>
</div>
Results are:
It's recommended to use Javascript to create and append the elements as variables, rather than appending strings of HTML at various points.
Additionally, you should confirm the DOM is loaded before targeting elements to avoid any bugs.
Refactored code with the points from above:
<script>
const fetchedData = fetch("./static/js/data.json");
window.addEventListener("DOMContentLoaded", (event) => {
fetchedData
.then((response) => response.json())
.then((data) => {
const table = document.getElementById("userdata");
for (var j = 0; j < 10; j++) {
const imgsrc = data.data[j].image;
const row = document.createElement("tr");
row.innerHTML = `<td rowspan="8"><img src=${imgsrc} width="150" height="150"></td>`;
for (var i = 0; i < 5; i++) {
const vmovieID = data.data[j].ingredients[i].contents;
const textContent = document.createTextNode(vmovieID);
const cell = document.createElement("td");
cell.appendChild(textContent);
row.appendChild(cell);
}
table.appendChild(row);
}
})
.catch((error) => {
console.error(new Error(error));
});
});
</script>
<div class="panel-body">
<table id="userdata">
<thead>
<th>Image</th>
<th>Dry Matter</th>
<th>CP</th>
<th>GE</th>
<th>Calcium</th>
</thead>
</table>
</div>
I have a problem with coding the sorting code for my database. With few data there is no problem but at this time I have to sort about 4000 data and it lasts about 20s, too long time.
By my check, the operation which lasts too much is insertBefore(...,...) function.
Can you please help me?
function sorting(list) {
var list_data = [];
var list_id = [];
for (var i = 0; i < list.length; i++) {
list_data[i] = Date.parse(list[i].cells[1].innerHTML);
list_id[i] = parseInt(list[i].cells[12].innerHTML);
}
//ordino gli array
for (var i = 0; i < list.length; i++) {
for (var j = 0; j < list.length-1; j++) {
if (list_data[j] > list_data[j+1]) {
tmp = list_data[j];
list_data[j] = list_data[j+1];
list_data[j+1] = tmp;
tmp = list_id[j];
list_id[j] = list_id[j+1];
list_id[j+1] = tmp;
}
}
}
//ordinato lista_id
var j = 0;
for (var i = 0; i < list.length; i++) {
j=i;
while (list_id[i] != parseInt(list[j].cells[12].innerHTML)) {
j++;
}
var target = list[i];
var newElement = list[j];
target.parentNode.insertBefore(newElement, target);
}
}
I have my table with 13 columns 0-12. The thirteenth column contains hidden cells with id of the data. I started with a bubblesort and then changed in this because i thought it could work better, but it still lasts 20s to sort. How suggested in comments I'm starting to think that a sort by server is better, but I don't know how to implement
I don't think it's the sorting. Created a snippet with time-logging, so you can see that a 5000 items long list's sorting is not that much of a problem.
Try setting up your project so that you control the data & only output the results (the snippet is a very simple example of that).
const tbody = document.getElementById('tbody')
let sortDesc = false
const rowHtml = (rowData) => {
return `
<tr>
<td>
${ rowData.first }
</td>
<td>
${ rowData.second }
</td>
</tr>
`
}
const setTable = (data) => {
tbody.innerHTML = ''
tbody.innerHTML = data.map(rowData => {
return rowHtml(rowData)
}).join('')
}
const sortData = (data, desc) => {
return data.sort((a, b) => {
if (desc) {
return b.first - a.first
} else {
return a.first - b.first
}
})
}
renderTable = (data) => {
console.time('sort data')
const d = sortData(data, sortDesc)
console.timeEnd('sort data')
sortDesc = !sortDesc
console.time('set table')
setTable(d)
console.timeEnd('set table')
}
let data = [];
(function() {
console.time('create items')
for (let i = 0; i < 5000; i++) {
data.push({
first: i,
second: `${ i }-${ i }`,
})
}
console.timeEnd('create items')
renderTable(data)
})();
const btnSort = document.getElementById('btnSort')
btnSort.addEventListener('click', function() {
renderTable(data)
})
<button id="btnSort">SORT</button><br />
<table id="table">
<tbody id="tbody"></tbody>
</table>
You can see from the time-logs that the real "expensive" stuff is actually putting out the HTML ("set table" in this case takes ~100 times as much time as "sort data").
This block of code is to create 3 arrays with the values pulled from the user's input in a popup menu in the HTML file, but the values here are needed to fill in the table below.
var arrM = new Array; var arrT = new Array; var arrA = new Array;
arrM[0] = mod0.mod.value; arrT[0] = mod0.target.value; arrA[0] = mod0.actual.value;
arrM[1] = mod1.mod.value; arrT[1] = mod1.target.value; arrA[1] = mod1.actual.value;
arrM[2] = mod2.mod.value; arrT[2] = mod2.target.value; arrA[2] = mod2.actual.value;
arrM[3] = mod3.mod.value; arrT[3] = mod3.target.value; arrA[3] = mod3.actual.value;
arrM[4] = mod4.mod.value; arrT[4] = mod4.target.value; arrA[4] = mod4.actual.value;
arrM[5] = mod5.mod.value; arrT[5] = mod5.target.value; arrA[5] = mod5.actual.value;
arrM[6] = mod6.mod.value; arrT[6] = mod6.target.value; arrA[6] = mod6.actual.value;
arrM[7] = mod7.mod.value; arrT[7] = mod7.target.value; arrA[7] = mod7.actual.value;
arrM[8] = mod8.mod.value; arrT[8] = mod8.target.value; arrA[8] = mod8.actual.value;
arrM[9] = mod9.mod.value; arrT[9] = mod9.target.value; arrA[9] = mod9.actual.value;
the code in between the block above and the block below(not shown here) is just to compute the average values and does not interact with the block below
the code below is to create a table with the same number of rows as the number of rows the user filled in the popup menu.
var tableGenerator = document.getElementById("tableGenerator");
tbl = document.createElement('table');
tbl.style.width = '500px';
tbl.style.height = '100px';
tbl.style.border = '1px solid black';
tbl.style.margin = '50px';
tbl.style.float = 'left';
if (j < 6) {
j = 6;
}
for (var a = 0; a < j+1; a++) {
var tr = tbl.insertRow();
for (var b = 0; b < 3; b++) {
if (a == j && b == 3) {
break;
} else {
var td = tr.insertCell();
td.appendChild(document.createTextNode(""));
td.style.border = '1px solid black';
if (a == 0 && b == 0) {
var newtext = document.createTextNode(Text);
var celltext = "Year " + year.value + " Semester " + semester.value;
td.appendChild(document.createTextNode(celltext));
td.setAttribute('colSpan', '3'); break;
}
//this else block below here obviously doesn't work, but this idea is there and I want something that
//works like the pseudo code below
else {
for (a = 1; a < j; a++) {
tbl[a][0] = arrM[a];
tbl[a][1] = arrT[a];
tbl[a][2] = arrA[a];
}
}
}
}
}tableGenerator.appendChild(tbl);
I am very unfamiliar with HTML/JS/CSS, is it possible for us to access cell values of a table as if it is an array? or is there any better way to do this?
In JavaScript you'll need to either create text nodes and assign the content of that node, or assign the content to the textContent, innerText or innerHTML properties to give the table cells their values.
td.textContent = 'Hello'; // This is the preferred property for text.
The help you achieve this it would be wise to structure your data in a way that you can loop over, because you're basically doing the same thing in a specific order. For example:
var data = [
arrM,
arrT,
arrA
];
This will put your arrays in another array. Now you can loop over the data array and create a table row for each array, and a table cell for each item in the nested array.
for (var i = 0; i < data.length; i++) {
// ... create table row.
for (var j = 0; j < data[i].length; j++) {
// ... create table cell and assign textContent property.
}
}
Examine the example below. It's a runnable version of the thing I've explained above. I hope it helps you out.
function createTable(headers, values) {
var table = document.createElement('table');
// Build <thead>
var tableHeader = table.createTHead();
// Create <tr> inside <thead>
var tableHeaderRow = tableHeader.insertRow();
for (var i = 0; i < headers.length; i++) {
// Create <th>
var tableHeaderCell = document.createElement('th');
// Set text of <th> to value in array.
tableHeaderCell.textContent = headers[i];
// Add <th> to <tr> inside <thead>
tableHeaderRow.appendChild(tableHeaderCell);
}
// Build <tbody>
var tableBody = table.createTBody();
for (var j = 0; j < values.length; j++) {
// Create <tr> inside <tbody>
var tableBodyRow = tableBody.insertRow();
for (var k = 0; k < values[j].length; k++) {
// Create <td> inside <tr>
var tableBodyCell = tableBodyRow.insertCell();
// Set text of <td> to value in array.
tableBodyCell.textContent = values[j][k];
}
}
// Add <table> to the <body>
document.body.appendChild(table);
}
var titles = [
'One',
'Two',
'Three'
];
var characters = [
['Batman', 'Robin', 'Batgirl'],
['Joker', 'Two-Face', 'Poison Ivy'],
['James Gordon', 'Alfred Pennyworth', 'Clayface']
];
createTable(titles, characters);
I'm trying to have a bunch of memes show up on my HTML page. I'm using this URL https://api.memegen.link/images. I'm having lots of trouble trying to display images. I cannot figure out how to use this link. The link has what looks like a bunch of JSON code and the actual website has very little documentation on how to use it.
Here's the Javascript code. The HTML is just 2 divs and an input that has an onClick that call the function
$(document).ready(function imagesFromJSON() {
$.getJSON("https://api.memegen.link/images", function (data) {
var arrItems = []; // The array to store JSON items.
$.each(data, function (index, value) {
arrItems.push(value); // Push values in the array.
});
// Extract values for the table header.
var col = [];
for (var i = 0; i < arrItems.length; i++) {
for (var key in arrItems[i]) {
if (col.indexOf(key) === -1) {
col.push(key);
}
}
}
var table = document.createElement("table");
var tr = table.insertRow(-1); // Table row.
for (var i = 0; i < col.length; i++) {
var th = document.createElement("th"); // Table header.
th.innerHTML = col[i];
tr.appendChild(th);
}
// Add JSON data to the table as rows.
for (var i = 0; i < arrItems.length; i++) {
tr = table.insertRow(-1);
for (var j = 0; j < col.length; j++) {
var tabCell = tr.insertCell(-1);
if (j === 2) { // The last JSON column has image urls.
// Create an <img> element to show the images.
var img = document.createElement('img');
img.src = arrItems[i].Image; // The image source from JSON array.
tabCell.appendChild(img);
}
else
tabCell.innerHTML = arrItems[i][col[j]];
}
}
// Finally, add the newly created <table> with data to a container.
var divContainer = document.getElementById("showData");
divContainer.innerHTML = "";
divContainer.appendChild(table);
});
});
You can use fetch API in JavaScript directly to call the memeAPI.
For generating the table inside your JavaScript, you can use Template literals which will make it easy for you to construct the tables.
const getMemeBtn = document.querySelector("#get-meme");
getMemeBtn.addEventListener("click", getMeme);
function getMeme(){
fetch("https://api.memegen.link/images")
.then(res => res.json())
.then(data => {
let HTMLContent = `<table>
<tr>
<th>Meme Template</th>
<th>Meme Image</th>
</tr>
`;
for(let i = 0; i < 5; i++){
let memeImgURL = data[i].url;
let memeName = data[i].template;
HTMLContent += `
<tr>
<td>${memeName}</td>
<td><img width="100" height="100" src="${memeImgURL}"></td>
</tr>
`;
}
HTMLContent += `</table>`;
document.getElementById("memes").innerHTML = HTMLContent;
})
.catch(err => console.log(err));
}
<button type="button" id="get-meme">Get Meme</button>
<br><br><br><br>
<div id="memes"></div>
So I'm using https://calendarific.com api and am trying to make an "app" where you can click on your country and it returns the holidays based on the current month. It kinda works except when I click on one country and then another the previous countries result stays on the top and the new country's holidays get put to the bottom of the page.
How can I remove previous results when a new one is made?
Javascript (sorry if it's a bit messy):
countrySelect.addEventListener('click', function() {
// Api url
let url = `https://calendarific.com/api/v2/holidays?&api_key=a7167178ffb6d2d7d8d9c1e05d98eab926f595e9&country=${buttonValue}&year=2020`;
fetch(url)
.then(res => res.json())
.then(data => {
// Filters holiday's to the current month
var currentMonthHolidays = data.response.holidays.filter(holiday => {
var holidayDate = new Date(holiday.date.iso);
var holidayMonth = holidayDate.getMonth();
var date = new Date();
var currentMonth = date.getMonth();
return currentMonth === holidayMonth;
})
// Build holiday table
function buildTable(data){
let table = document.getElementById('resultTable');
let col = [];
// Get the index of the api titles
for (let i = 0; i < currentMonthHolidays.length; i++) {
for (let key in currentMonthHolidays[i]) {
if (col.indexOf(key) === -1) {
col.push(key);
}
}
console.log(col)
}
//Create table header row using the extracted headers above.
let tr = table.insertRow(-1); // table row.
for (let i = 0; i < col.length; i++) {
let th = document.createElement("th"); // table header.
th.innerHTML = col[i];
tr.appendChild(th);
}
// add json data to the table as rows.
for (let i = 0; i < currentMonthHolidays.length; i++) {
tr = table.insertRow(-1);
for (let j = 0; j < col.length; j++) {
let tabCell = tr.insertCell(-1);
tabCell.innerHTML = currentMonthHolidays[i][col[j]];
}
}
}
buildTable(currentMonthHolidays);
console.log(currentMonthHolidays);
//handles error
}, networkError => {
alert(networkError)
})
})
If you are only concerned about just getting new data on top,
in your code just add :
table.removeChild(table.tBodies[0]);
which becomes :-
countrySelect.addEventListener('click', function() {
// Api url
let url = `https://calendarific.com/api/v2/holidays?&api_key=a7167178ffb6d2d7d8d9c1e05d98eab926f595e9&country=${buttonValue}&year=2020`;
fetch(url)
.then(res => res.json())
.then(data => {
// Filters holiday's to the current month
var currentMonthHolidays = data.response.holidays.filter(holiday => {
var holidayDate = new Date(holiday.date.iso);
var holidayMonth = holidayDate.getMonth();
var date = new Date();
var currentMonth = date.getMonth();
return currentMonth === holidayMonth;
})
// Build holiday table
function buildTable(data){
let table = document.getElementById('resultTable');
let col = [];
// Get the index of the api titles
for (let i = 0; i < currentMonthHolidays.length; i++) {
for (let key in currentMonthHolidays[i]) {
if (col.indexOf(key) === -1) {
col.push(key);
}
}
console.log(col)
}
//Create table header row using the extracted headers above.
let tr = table.insertRow(-1); // table row.
for (let i = 0; i < col.length; i++) {
let th = document.createElement("th"); // table header.
th.innerHTML = col[i];
tr.appendChild(th);
}
/*
since all <tr> are wrapped inside <tbody>, so just remove the old one and you are good to go
*/
table.removeChild(table.tBodies[0]);
// add json data to the table as rows.
for (let i = 0; i < currentMonthHolidays.length; i++) {
tr = table.insertRow(-1);
for (let j = 0; j < col.length; j++) {
let tabCell = tr.insertCell(-1);
tabCell.innerHTML = currentMonthHolidays[i][col[j]];
}
}
}
buildTable(currentMonthHolidays);
console.log(currentMonthHolidays);
//handles error
}, networkError => {
alert(networkError)
})
})