API contains JSON data how to render on HTML and JavaScript? - javascript

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>

Related

how to add button in javascript since the data that import in the html table is from JSON file

I am trying to add edit and delete button inside the column but the HTML table was created from JSON file and it is using for loop to print out the content. I don't know how to add extra button inside the column (green zone).
The button that plan to add will be replace in the 'undefined' col.
JSON code:
[
{
"userId":"ravjy",
"jobTitleName":"Developer",
"firstName":"Ran",
"lastName":"Vijay",
"preferredFullName":"Ran Vijay",
"employeeCode":"H9",
"region":"DL",
"phoneNumber":"34567689",
"emailAddress":"ranvijay.k.ran#gmail.com"
},
{
"userId":"mrvjy",
"jobTitleName":"Developer",
"firstName":"Murli",
"lastName":"Vijay",
"preferredFullName":"Murli Vijay",
"employeeCode":"A2","region":"MU",
"phoneNumber":"6543565",
"emailAddress":"murli#vijay.com"
}
]
<script>
fetch('employees.json')
.then(function (response) {
// The JSON data will arrive here
return response.json();
})
.then(function (data) {
appendData(data);
})
.catch(function (err) {
// If an error occured, you will catch it here
});
function appendData(data) {
//Extract Value for HTML HEADER.
var col=[];
for (var i = 0; i<data.length;i++){
for (var key in data[i]){
if (col.indexOf(key) === -1){
col.push(key);
}
}
}
//Add edit and delete header
col.push("Edit","Delete");
// CREATE DYNAMIC TABLE.
var table = document.createElement("table");
// CREATE HTML TABLE HEADER ROW USING THE EXTRACTED HEADERS ABOVE.
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 < data.length; i++) {
tr = table.insertRow(-1);
for (var j = 0; j < col.length; j++) {
var tabCell = tr.insertCell(-1);
tabCell.innerHTML = data[i][col[j]];
}
}
// FINALLY ADD THE NEWLY CREATED TABLE WITH JSON DATA TO A CONTAINER.
var divContainer = document.getElementById("myData");
divContainer.innerHTML = "";
divContainer.appendChild(table);
}
</script>
[1]: https://i.stack.imgur.com/YpoDi.png
[2]: https://i.stack.imgur.com/pu7SB.png
Solution
Javascript map will help to get that working
const data = [
{
userId: "ravjy",
jobTitleName: "Developer",
firstName: "Ran",
lastName: "Vijay",
preferredFullName: "Ran Vijay",
employeeCode: "H9",
region: "DL",
phoneNumber: "34567689",
emailAddress: "ranvijay.k.ran#gmail.com",
},
{
userId: "mrvjy",
jobTitleName: "Developer",
firstName: "Murli",
lastName: "Vijay",
preferredFullName: "Murli Vijay",
employeeCode: "A2",
region: "MU",
phoneNumber: "6543565",
emailAddress: "murli#vijay.com",
},
];
function test(type, id) {
alert(type + " " + id);
}
function appendData(data) {
//Extract Value for HTML HEADER.
data = data.map((item) => {
item.Edit_Delete = `<Button type="button" onclick="test('Edit', '${item.userId}')">${item.userId}</Button>
<Button type="button" onclick="test('Delete', '${item.userId}')">${item.userId}</Button>`;
return item;
});
const col = [];
for (let i = 0; i < data.length; i++) {
for (let key in data[i]) {
if (col.indexOf(key) === -1) {
col.push(key);
}
}
}
//Add edit and delete header
// col.push("Edit","Delete");
// CREATE DYNAMIC TABLE.
const table = document.createElement("table");
// CREATE HTML TABLE HEADER ROW USING THE EXTRACTED HEADERS ABOVE.
let tr = table.insertRow(-1); // TABLE ROW.
for (let i = 0; i < col.length; i++) {
const 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 < data.length; i++) {
tr = table.insertRow(-1);
for (let j = 0; j < col.length; j++) {
const tabCell = tr.insertCell(-1);
tabCell.innerHTML = data[i][col[j]];
}
}
// FINALLY ADD THE NEWLY CREATED TABLE WITH JSON DATA TO A CONTAINER.
const divContainer = document.getElementById("myData");
divContainer.innerHTML = "";
divContainer.appendChild(table);
}
appendData(data);
<!DOCTYPE html>
<html>
<body>
<div id ="myData"></div>
</body>
</html>

How to clear previous api result when a new query is made

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

Change the Title of Elements on a Table

I'm currently using the following code to create a table based on a JSON API. I want to change the title of the table columns to be Name and Score instead of userName and userScore...
I have tried adjusting the forEach statement that creates the table columns, but that didn't work...
axios
.get("[ip censored]/scores")
.then(function(response) {
let sortedList = response.data.sort((a, b) => b.userScore - a.userScore);
console.warn(sortedList);
// EXTRACT VALUE FOR HTML HEADER.
var col = [];
for (var i = 0; i < sortedList.length; i++) {
for (var key in sortedList[i]) {
if (
col.indexOf(key) === -1 &&
(key === "userName" || key === "userScore")
) {
col.push(key);
}
}
}
// CREATE DYNAMIC TABLE.
var table = document.createElement("table");
// CREATE HTML TABLE HEADER ROW USING THE EXTRACTED HEADERS ABOVE.
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 < sortedList.length; i++) {
tr = table.insertRow(-1);
for (var j = 0; j < col.length; j++) {
var tabCell = tr.insertCell(-1);
tabCell.innerHTML = sortedList[i][col[j]];
}
}
// FINALLY ADD THE NEWLY CREATED TABLE WITH JSON DATA TO A CONTAINER.
var divContainer = document.getElementById("leaderboard");
divContainer.innerHTML = "";
divContainer.appendChild(table);
})
.catch(function(error) {
console.error(error);
});
I also tried using CSS to make the tables look prettier, but it still didn't work.
Given you know the incoming key names and that they're consistent a simple inline if/else in your JavaScript should be all you need.
Try this:
for (var i = 0; i < col.length; i++) {
var th = document.createElement("th"); // TABLE HEADER
// This inline if says if col[i] is userName then set innerHTML to Name, else Score
th.innerHTML = col[i]==='userName' ? 'Name' : 'Score';
tr.appendChild(th);
}
Never mind, I figured it out. I used an if statement, and if col[i] equaled the value I wanted, I changed the value before I pushed the table.
You can use an if statement.
for (var i = 0; i < col.length; i++) {
var th = document.createElement("th"); // TABLE HEADER.
var heading = "";
if(col[i] == "userName"){
th.innerHTML = "Name";
}
else if(col[i] == "userScore"){
th.innerHTML = "Score";
}
tr.appendChild(th);
}

Filter Table Data, and Remove Filtered Column

I am currently using:
function searchNotes() {
const url = "http://localhost:2609/api/notes"
$.ajax({
url: url,
type: 'GET',
success: function (notesList) {
console.log(notesList)
// EXTRACT VALUE FOR HTML HEADER.
var col = [];
for (var i = 0; i < notesList.length; i++) {
for (var key in notesList[i]) {
if (col.indexOf(key) === -1 && (key === 'title' || key === 'content' || key == 'category' || key == 'categoryId')) {
col.push(key);
}
}
}
// CREATE DYNAMIC TABLE.
var table = document.createElement("table");
// CREATE HTML TABLE HEADER ROW USING THE EXTRACTED HEADERS ABOVE.
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 < notesList.length; i++) {
tr = table.insertRow(-1);
for (var j = 0; j < col.length; j++) {
var tabCell = tr.insertCell(-1);
tabCell.innerHTML = notesList[i][col[j]];
}
}
// FINALLY ADD THE NEWLY CREATED TABLE WITH JSON DATA TO A CONTAINER.
var divContainer = document.getElementById("listNotes");
divContainer.innerHTML = "";
divContainer.appendChild(table);
}
});
}
to create a html table using jquery. The table looks like this:
I want to filter the table by categoryId, as chosen in the dropdown at the top, then I want to remove the categoryId column. Any ideas how I could achieve this?
You need to use .sort() on the notesList object, something like this:
notesList.sort(function(a, b) {
return a.categoryId - b.categoryId;
});
Put it before appending the values to the html.
To 'remove' the categoryId column is very simple: Just remove the followingen bit from the if statement:
|| key == 'categoryId'
So your end result is something like this:
function searchNotes() {
const url = "http://localhost:2609/api/notes"
$.ajax({
url: url,
type: 'GET',
success: function (notesList) {
notesList.sort(function(a, b) {
return a.categoryId - b.categoryId;
});
// EXTRACT VALUE FOR HTML HEADER.
var col = [];
for (var i = 0; i < notesList.length; i++) {
for (var key in notesList[i]) {
if (col.indexOf(key) === -1 && (key === 'title' || key === 'content' || key == 'category')) {
col.push(key);
}
}
}
// CREATE DYNAMIC TABLE.
var table = document.createElement("table");
// CREATE HTML TABLE HEADER ROW USING THE EXTRACTED HEADERS ABOVE.
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 < notesList.length; i++) {
tr = table.insertRow(-1);
for (var j = 0; j < col.length; j++) {
var tabCell = tr.insertCell(-1);
tabCell.innerHTML = notesList[i][col[j]];
}
}
// FINALLY ADD THE NEWLY CREATED TABLE WITH JSON DATA TO A CONTAINER.
var divContainer = document.getElementById("listNotes");
divContainer.innerHTML = "";
divContainer.appendChild(table);
}
});
}

Put certain JSON data arrays into a table after using getJson command

How do I use the below code to pull certain details like country name and capital only into a table with drop down headers? Or can you suggest any plain English Youtube videos where I can learn how to do this or example courses where I can teach myself.
<script>
$(document).ready(function () {
//for example details in url below
var url = 'https://restcountries.eu/rest/v1/all';
$.getJSON(url, function (data) {
console.log(data)
// var arrItems = []; // THE ARRAY TO STORE JSON ITEMS.
// $.each(data, function (index, value) {
// arrItems.push(value); // PUSH THE VALUES INSIDE THE ARRAY.
// });
console.log(arrItems)
// EXTRACT VALUE FOR TABLE HEADER.
var col = [];
var arrItems = data.countries;
console.log(arrItems)
var firstCountry = arrItems[0]
console.log(firstCountry)
for (var i = 0; i < arrItems.length; i++) {
for (var key in arrItems[i]) {
if (col.indexOf(key) === -1) {
col.push(key);
}
}
}
// CREATE DYNAMIC TABLE.
var table = document.createElement("table");
// CREATE HTML TABLE HEADER ROW USING THE EXTRACTED HEADERS ABOVE.
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);
tabCell.innerHTML = arrItems[i][col[j]];
}
}
// FINALLY ADD THE NEWLY CREATED TABLE WITH JSON DATA TO A CONTAINER.
var divContainer = document.getElementById("showData");
divContainer.innerHTML = "";
divContainer.appendChild(table);
});
});
There's a lot of looping inside of looping, which can increase the time and space complexity - meaning, the more data, the slower this solution will become as well as in general this looks like it will be difficult to maintain.
I would first put as much of the html that you can in the static html and just append the dynamic html to the <tbody>.
You can use the Array.reduce static method to generate a string from your data. One thing you can do to make this easier to understand is stick with either mostly appending DOM nodes or using innerHTML. If you stick with innerHTML, you can create template strings for the cells and the rows.
This will make the code more declarative in nature and functional as well as composeable.
$(document).ready(function() {
//for example details in url below
var url = 'https://restcountries.eu/rest/v1/all';
$.getJSON(url, function(data) {
const html = buildHTML(data);
const tbody = document.querySelector('#showData tbody');
tbody.innerHTML = html;
});
});
const tableCellTemplate = (val) => {
return `<td>${val}</td>`;
};
const tableRowTemplate = (val) => {
return `<tr>${val}</tr>`;
};
function buildHTML(data) {
return data.reduce((prev, next) => {
const nameCell = tableCellTemplate(next.name);
const codeCell = tableCellTemplate(next.alpha2Code);
return prev + tableRowTemplate(nameCell + codeCell);
}, '');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="showData">
<table>
<thead>
<tr>
<th>Name</th>
<th>alpha2Code</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>

Categories

Resources