I'm trying to get my code to output an api object to the html file.
const container = document.createElement('div');
container.setAttribute('class', 'container');
obj = fetch('https://apis.is/concerts')
.then(function(response) {
return response.json();
})
.then(function(data) {
return obj = data;
})
.then(() => idk())
function idk() {
let count = 0;
for(key in obj.results) {
count++;
};
console.log(count);
for(let i = 0; i < count; i++) {
const card = document.createElement('div');
card.setAttribute('class', 'card');
const h1 = document.createElement('h1');
h1.textContent = obj.results[i].eventDateName;
const p = document.createElement('p');
p.textContent = obj.results[i].dateOfShow;
container.appendChild(card);
card.appendChild(h1);
card.appendChild(p);
};
};
I have been trying to use DOM to create elements for the html file but it's like some of the code is being ignored.
If you want to render all the DOM you are creating you have to somehow add it to the DOM tree that browser is displaying. The simples way would be to add it to body node. document.querySelector('body').appendChild(container); once you're done with data processing.
But I would suggest to refactor your code a bit. For instance in this step you are assigning results to the original object where you are saving the promise with the results. Also that is a global object so pretty quick you might end up with a race condition.
.then(function(data) {
return obj = data;
})
Also the idk() function is coupled to that very specific variable obj which would make it really hard to test.
obj = fetch('https://apis.is/concerts')
.then(function(response) {
return response.json(); //subscribe to response stream
})
.then((response) => {
const allEvents = eventsDomTree(response.results); // create the events DOM tree based on response
document.querySelector('body').appendChild(allEvents); //append the created list to document DOM tree
});
function eventsDomTree(events) {
const allEvents = document.createElement('div');
events.forEach((event) => {
const card = document.createElement('div');
card.setAttribute('class', 'card');
const eventName = document.createElement('h1');
eventName.textContent = event.eventDateName;
const dateOfShow = document.createElement('p');
dateOfShow.textContent = event.dateOfShow
card.appendChild(eventName);
card.appendChild(dateOfShow);
allEvents.appendChild(card);
});
return allEvents;
}
Related
i know that the problem is that let todoList is an empty array, but i dont know how to solve it.
the id tags in my created html is so e can create a delete button later
heres my code:
const textArea = document.querySelector("textarea");
const button = document.querySelector("button");
const listContainer = document.querySelector(".list-container");
let id = 0;
let todoList = [];
button.onclick = function () {
const listItem = {
title: textArea.value,
};
todoList.push(listItem);
addToStorage(todoList);
const dataFromStorage = getFromStorage();
createHtml(dataFromStorage);
};
function addToStorage(items) {
const stringify = JSON.stringify(items);
localStorage.setItem("list", stringify);
}
function getFromStorage() {
const data = localStorage.getItem("list");
const unstrigified = JSON.parse(data);
return unstrigified;
}
const createHtml = (data) => {
id++;
listContainer.innerHTML = "";
data.forEach((item) => {
listContainer.innerHTML += `<div class="list-item" data-id=${id}><p>${item.title} </p><button class="remove" data-id=${id}>Delete</button></div>`;
});
};
The problem here is you just forgot to load the data from localStorage when the page loaded like this
window.onLoad = () => {
const dataFromStorage = getFromStorage();
if(dataFromStorage){
createHtml(dataFromStorage);
} else {
createHtml([]);
}
}
The problem in the code is as follows
Initially the todolist will be an empty array. so when you do the below
todoList.push(listItem);
// adding to local storage which will override the existing todos when page is refreshed
addToStorage(todoList);
// So when the below line is executed only the latest todo will be returned
const dataFromStorage = getFromStorage();
createHtml(dataFromStorage);
Fix:
Initialise the todos from localstorage instead of an empty array
let todoList = [];
// change it as below
let todoList = getFromStorage();
Now Modify the getFromStorage() as below
// If the data is present in the localStorage then return it, else return empty array
function getFromStorage() {
const data = localStorage.getItem("list");
if (!data) return [];
const unstrigified = JSON.parse(data);
return unstrigified;
}
Now when the page is loaded, we need to display the todos. Add the below lines of code
window.onload = function () {
createHtml(todoList);
};
That's it. This will fix the issue.
Few minor improvements can be made as well.
todoList.push(listItem);
addToStorage(todoList);
const dataFromStorage = getFromStorage(); // this line is not necessary, remove it
createHtml(dataFromStorage); // change this to createHtml(todoList)
Codepen
Thanks.
I have the html page. In that HTML page, Iust want to clone all elements like head,body and other elements .
I can able to get like this
const getHeadEle = () => {
const newHead = document.head.cloneNode(true);
return newHead.innerHTML;
}
const getBody = () => {
const head = document.head.cloneNode(true);
const dom = document.createElement('div');
dom.innerHTML = document.body.innerHTML;
return dom.innerHTML;
}
const html = `<!doctype html><html lang="en"><head>${getHeadEle()}</head><body>${getBody()}</body></html>`;
For now, I get the head element and body element into separate method. Is possible to clone all documents in a line of code?
try it ...
const getdocument = () => {
const newDocument = document.cloneNode(true);
return newDocument ;
}
const html = getdocument() ;
I have a simple fetch function that gets data (messages from db) and putting it into an array to display it with simple vanilla JS. The thing is I am calling this function every 2 seconds in order to check for new messages. But when I do that I duplicate my messages and it keeps adding instead of replacing. I am struggling to understand what I should do to change, not add.
(a little dummy question, sorry)
const list = document.getElementById('message-list');
const getData = () => {
fetch('/messages')
.then((resp) => resp.json())
.then(function(data) {
console.log(data)
for (let i = 0; i < data.length; i++) {
const listItem = document.createElement('li');
listItem.innerText = data[i].message;
const delButton = document.createElement('button');
delButton.innerHTML = 'Delete';
delButton.addEventListener('click', ()=>{
const message_id = data[i].message_id;
deleteItem(message_id);
})
listItem.appendChild(delButton);
list.appendChild(listItem)
}
})
}
setInterval(getData,2000)
Make a Set of the message_ids processed so far, and on further calls, ignore messages matching that message_id:
const seenIds = new Set();
const getData = () => {
fetch('/messages')
.then((resp) => resp.json())
.then(function(data) {
data
.filter(({ message_id }) => !seenIds.has(seenIds))
.forEach(({ message, message_id }) => {
seenIds.add(message_id);
const listItem = document.createElement('li');
listItem.innerText = message;
const delButton = document.createElement('button');
delButton.textContent = 'Delete';
delButton.addEventListener('click', () => {
deleteItem(message_id);
});
listItem.appendChild(delButton);
list.appendChild(listItem)
});
});
};
That said, it would probably be better to change your backend so that it can filter the items for you, rather than sending objects over the net that proceed to get ignored.
Hi I have been trying to fetch from two API's using a fetch chain, the fetch works and the data displays correctly using console.log inside the getallproducts function but when I try to make a callback towards the displayproducts function using the data, the data is nowhere to be seen. I do not know exactly what I am doing wrong or if im using the wrong method for this but I have been trying multiple methods of fetch. promise.all seemed to be a solution but that didn't work either.
showProductsPage function
function showProductsPage() {
var page = document.getElementById('products-page');
hideAllPages();
//getAllProducts();
displayproducts(getAllProducts);
page.style.display = 'block';
}
getallproducts function
function getAllProducts(callback){
var producten;
var authors;
fetch(window.location.href+"api/products")
.then(response => response.json())
.then(data => {
producten = data.products;
console.log(data);
callback(data)
return fetch(window.location.href+"api/authors")
}).then(response => response.json())
.then(data => {
authors = data.authors;
callback(data)
})
}
display products function
function displayproducts(data) {
console.log(data.products);
for (var i = 0; i < data.products.length; i++) {
var card = document.createElement("div");
var img = document.createElement("img");
var name = document.createElement("BUTTON");
var author = document.createElement("p");
var published = document.createElement("p");
var price = document.createElement("p");
var cart = document.createElement("BUTTON");
document.getElementById("products-page").appendChild(card);
//
card.appendChild(img);
card.appendChild(name);
card.appendChild(author);
card.appendChild(published);
card.appendChild(price);
card.appendChild(cart);
//
card.setAttribute("class", "book-card");
img.setAttribute("class", "product-img");
name.setAttribute("class", "book-title");
author.setAttribute("class", "author");
published.setAttribute("class", "published");
price.setAttribute("class", "price");
cart.setAttribute("class", "add-to-cart");
//
cart.innerHTML = "Add to Cart";
name.innerHTML = data.products.title;
price.innerHTML = data.products.price;
};
//console.log(producten[1].price);
}
You mixed up the call. This:
displayproducts(getAllProducts)
Must be:
getAllProducts(displayproducts);
Trying to fetch data from an API and add it to the DOM
Specifically, an array that contains objects.
Below is an example of what the API returns in the console.
I’m using a for loop and a for…in loop to access the array within the object
Code below
const getNews = document.getElementById('btn')
heyThere = () => {
axios.get('https://newsapi.org/v2/top-headlines?country=us&category=business&apiKey=APIKEY')
.then(function (response) {
for (let i = 0; i <= response.data.articles.length; i++) {
for (key in response.data.articles[i]) {
ham.innerHTML = (response.data.articles)
}
}
console.log(response)
console.log(typeof response)
})
.catch(function (error) {
console.log(error);
})
}
getNews.addEventListener('click', heyThere)
The above code prints the following to the DOM
What’s the correct way to access the full list of articles(20 articles) and print them to the DOM?
You need to access the specific properties of response.data.articles[i] that you want to display, and create the desired HTML for each of them. Something like:
const getNews = document.getElementById('btn')
heyThere = () => {
axios.get('https://newsapi.org/v2/top-headlines?country=us&category=business&apiKey=APIKEY')
.then(function(response) {
let html = '';
response.data.articles.each(article => {
html += '<div class="article">';
html += `<div class="author">${article.author}</div>`;
html += `<div class="description">${article.description}</div>`;
html += '</div>';
});
ham.innerHTML = html;
console.log(response)
console.log(typeof response)
})
.catch(function(error) {
console.log(error);
})
}
getNews.addEventListener('click', heyThere)
The solution below prints the articles to the DOM as a list.
heyThere = () => {
axios.get('https://newsapi.org/v2/top-headlines?country=us&category=business&apiKey=APIKEY')
.then(function (response) {
let news = response.data.articles
for (let i = 0, len = news.length; i < len; i++) {
console.log(news[i])
let li = document.createElement('li')
li.innerHTML = JSON.stringify(news[i].title)
document.querySelector('#ham').appendChild(li)
}
})
.catch(function (error) {
console.log(error);
})
}
getNews.addEventListener('click', heyThere)
Below are the articles printed to the page
Altering the response with dot notation allows one to return a list of URLs, authors, etc. For example, li.innerHTML = JSON.stringify(news[i].url)
Hope this is helpful!