Repo: https://github.com/bigolboyyo/weatherdbapp
Hello! I am working on a small project working with an API for the first time. I'm making a simple weather app that allows you to type in a location and append a "card" of data.
This card has a "front" and "back". Front being the weather data and the back being a simple textarea notepad.
As far as functionality goes I am just about there. My only issue is now when I have more than one card I only get an event listener on the first card button and the first card's button affects all the other cards created after! How would I apply the event listener for each card's buttons made and have those buttons only affect the relevant card?
Current code I'm working with
let notesBtn = document.getElementById("notes-btn");
notesBtn.addEventListener("click", handleFrontClick);
console.log(notesBtn);
function handleFrontClick(e) {
e.target.parentNode.remove();
card.appendChild(back);
let frontBtn = document.getElementById("front-btn");
frontBtn.addEventListener("click", (e) => {
e.target.parentNode.remove();
card.appendChild(front);
});
ALL JS (git repo above)
const body = document.getElementsByTagName("body");
const unsplashRandom =
"https://source.unsplash.com/random/1920x1080/?landscapes";
document.body.style.backgroundImage = `url(${unsplashRandom})`;
const header = document.createElement("div");
header.className = "header";
header.id = "header";
document.body.append(header);
const container = document.createElement("div");
container.className = "container";
document.body.append(container);
const h1 = document.createElement("h1");
h1.id = "h1";
h1.textContent = "WeatherDB Search";
h1.style.textAlign = "center";
header.append(h1);
let p1 = document.createElement("p");
p1.id = "p1";
p1.textContent = "Enter location for today's weather!";
p1.style.textAlign = "center";
header.append(p1);
const cityInput = document.createElement("input");
cityInput.className = "search-inputs";
cityInput.id = "city-input";
cityInput.placeholder = " ex: New York, Toronto, London";
header.append(cityInput);
const searchButton = document.createElement("button");
searchButton.className = "buttons";
searchButton.id = "search-btn";
searchButton.textContent = "🔍";
let br = document.createElement("br");
header.append(br);
header.append(searchButton);
function fetchWeather(e) {
let userInput = cityInput.value;
let config = {
Headers: {
"Content-type": "application/json",
},
};
return fetch(
`https://weatherdbi.herokuapp.com/data/weather/${userInput}`,
config
)
.then((res) => res.json())
.then((json) => weatherSearch(json, userInput))
.catch((err) => {
window.alert(
`${err} \n https://weatherdbi.herokuapp.com/data/weather/${userInput}`
);
console.log(err);
});
}
function weatherSearch(e, userInput) {
cityInput.value = "";
let weatherKeys = Object.keys(e.currentConditions);
let weatherValues = Object.values(e.currentConditions);
let temps = Object.values(weatherValues[1]);
let speeds = Object.values(weatherValues[4]);
const card = document.createElement("div");
card.id = `${userInput}-card`;
card.className = "cards";
container.append(card);
const front = document.createElement("div");
front.id = `${userInput}-front`;
front.className = "front";
front.innerHTML = `
<h1>${userInput.toUpperCase()}</h1>
<p>Time: ${weatherValues[0]}</p>
<li id="comment">Comment: ${weatherValues[6]}</li>
<li id="precipitation">Precipitation: ${weatherValues[2]}
<li id="temp">Temp: ${temps[0]}c | ${temps[1]}f</li>
<li id="humidity">Humidity: ${weatherValues[3]}</li>
<li id="wind">Wind Speed: ${speeds[0]}km | ${speeds[1]}mile</li>
</br>
<button id="notes-btn" class="buttons">Notes</button>
`;
card.append(front);
const back = document.createElement("div");
back.id = `${userInput}-back`;
back.className = "back";
back.innerHTML = `
<textarea id="back-text" name="backtext"
rows="25" placeholder="NotePad">
</textarea>
</br>
<button id="front-btn">Flip</button>
`;
let notesBtn = document.getElementById("notes-btn");
notesBtn.addEventListener("click", handleFrontClick);
console.log(notesBtn);
function handleFrontClick(e) {
e.target.parentNode.remove();
card.appendChild(back);
let frontBtn = document.getElementById("front-btn");
frontBtn.addEventListener("click", (e) => {
e.target.parentNode.remove();
card.appendChild(front);
});
}
}
document.addEventListener("DOMContentLoaded", (e) => {
searchButton.addEventListener("click", (e) => {
fetchWeather();
});
document.addEventListener("keydown", function (e) {
if (e.key === "Enter" && cityInput.value.length > 0) {
fetchWeather();
}
});
});
Related
I'm having trouble implementing the logic that will limit me from adding the same items to my shopping list. When the item is the same, I just want to display the quantity with the existing item.
<div class="pizzas">
</div>
<div class="shoppingCart">
<p class="totalPrice">Hungry? order our pizzas</p>
</div>
// js
fetch("https://raw.githubusercontent.com/alexsimkovich/patronage/main/api/data.json")
.then(data => data.json())
.then(data => {
let valueCurrency = 0;
data.forEach(element => {
const shoppingCart = document.querySelector(".shoppingCart");
const pizzas = document.querySelector(".pizzas");
const box = document.createElement("div");
const img = document.createElement("img");
const title = document.createElement("h3");
const ingredients = document.createElement("p");
const price = document.createElement("h4");
const btn = document.createElement("button");
const totalPrice = document.querySelector(".totalPrice");
box.className = "box";
ingredients.className = "ingredients"
btn.className = "btn";
img.src = element.image;
img.className = "img";
title.innerHTML = element.title;
ingredients.innerHTML = element.ingredients;
price.innerHTML = element.price.toFixed(2) + " zł";
btn.innerHTML = "Dodaj do koszyka";
box.appendChild(img);
box.appendChild(title);
box.appendChild(ingredients);
box.appendChild(price);
box.appendChild(btn);
pizzas.appendChild(box);
btn.addEventListener("click", (e) => {
valueCurrency = valueCurrency + element.price;
const pizza = document.createElement("div");
pizza.className = "pizzaList";
const pizzasList = document.createElement("li");
const pizzaPrice = document.createElement("p");
const btnRemove = document.createElement("button");
btnRemove.innerText = "X";
pizzasList.innerText = title.textContent;
pizzaPrice.innerText = price.textContent;
pizza.appendChild(pizzasList);
pizza.appendChild(pizzaPrice);
pizza.appendChild(btnRemove);
totalPrice.innerText = "Całkowita cena: " + valueCurrency.toFixed(2);
if(pizzasList.innerText === pizzasList.innerText)
{
// don't add another item to the list
// just add +1 to existing element
}
else
{
// add an item to the list
shoppingCart.prepend(pizza);
}
btnRemove.addEventListener("click", (e) => {
pizza.remove();
valueCurrency = valueCurrency - element.price;
totalPrice.innerText = "Całkowita cena: " + valueCurrency.toFixed(2);
})
})
});
})
.catch(err => console.log(err));
My problem is exactly in the conditional statement, I don't know exactly how to implement the counting of the same pizzas option.
Thank you in advance for your help.
Since you are using html elements for this, what you can do is to use a data-attribute in your pizza element and increment it each time you need.
Something like:
if(pizzasList === pizzasList)
{
pizza.dataset.total = Number(pizza.dataset.total) + 1;
}
else
{
pizza.dataset.total = 1;
shoppingCart.prepend(pizza);
}
Then just use pizza.dataset.total to retieve the total number of repetitions.
I'm trying to implement server side pagination with NodeJS/Express. But the frontend rendering of it isn't working as expected. I fetch from a third-party API and implement the logic for the pagination. I then connect it to the frontend for rendering.
I have created cards to render the information from the API, first time remove the cards to render next page elements/cards with the code:
if(card !== undefined){
card.remove();
}
It works and it removes the cards, you can see this in the frontend, first eventlistener. But when I try to implement the same in the second eventlistener the elements/cards aren't removed and replaced with new ones.
Pagination - Backend
const express = require('express');
const router = express.Router();
const fetch = require('node-fetch');
router.get('/pokemon', function(req, res) {
async function getPokemonInfo(){
return fetch('https://pokeapi.co/api/v2/pokemon?limit=251')
.then(response => response.json())
.then(data => {
getDetailsPokemon(data)
}).catch(error => {
console.log(error);
})
}
getPokemonInfo()
async function getDetailsPokemon(pokemon){
const pokemonArr = pokemon.results;
const eachPokemon = pokemonArr.map(pokeEl => {
return fetch(pokeEl.url)
.then(response => response.json())
.catch(error => {
console.log(error);
})
})
Promise.all(eachPokemon)
.then(values => {
const page = parseInt(req.query.page);
const limit = parseInt(req.query.limit);
console.log(page, limit);
const startIndex = (page - 1) * limit;
const endIndex = page * limit;
console.log(startIndex, endIndex);
const results = {}
if(endIndex < values.length){
results.next = {
page: page + 1,
limit: limit
}
}
if(startIndex > 0){
results.previous = {
page: page - 1,
limit: limit
}
}
results.result = values.slice(startIndex, endIndex);
console.log(results);
res.json(results)
})
}
})
module.exports = router;
Pagination - Frontend
const paginatedApp = {
paginatedPokemon: async function(){
await fetch(`http://localhost:1337/pokemon?page=1&limit=20`)
.then(response => response.json())
.then(data => {
this.createCards(data)
})
},
createCards: function(pokemonObj){
let next = document.querySelector('.next');
let previous = document.querySelector('.previous');
pokemonObj.result.map(pokeEl => {
// Variables
let main = document.querySelector('main');
let card = document.createElement('div');
let imgHolder = document.createElement('div');
let img = document.createElement('img');
let infoHolder = document.createElement('div');
let infoBoxOne = document.createElement('div');
let infoBoxTwo = document.createElement('div');
let pId = document.createElement('p');
let pName = document.createElement('p');
let boxForType = document.createElement('div');
let id = document.createTextNode('id:');
let name = document.createTextNode('name:');
let type = document.createTextNode('type:');
// Info box 1
let infoPId = document.createElement('p');
let infoPName = document.createElement('p');
let infoPType = document.createElement('p');
infoPId.append(id);
infoPName.append(name);
infoPType.append(type);
infoBoxOne.append(infoPId, infoPName, infoPType);
infoBoxTwo.append(pId, pName, boxForType);
// Lägg till klasser
card.classList.add('card');
imgHolder.classList.add('imgHolder');
infoHolder.classList.add('infoHolder');
boxForType.classList.add('boxForType');
img.classList.add('img');
infoHolder.classList.add('infoHolder');
pId.classList.add('id');
pName.classList.add('name');
infoBoxOne.classList.add('infoBoxOne');
infoBoxTwo.classList.add('infoBoxTwo');
img.src = pokeEl.sprites.other['official-artwork']['front_default'];
pId.append(`#${pokeEl.id}`);
pName.append(pokeEl.name);
// Types
pokeEl.types.map(pokeType => {
let pokemonType = pokeType.type.name
let pokes = document.createElement('p');
pokes.append(pokemonType)
boxForType.append(pokes);
})
imgHolder.appendChild(img);
card.appendChild(imgHolder)
main.appendChild(card);
infoHolder.append(infoBoxOne)
infoHolder.append(infoBoxTwo)
card.appendChild(infoHolder);
boxForType.children[0].style.border = '1px solid #fff';
boxForType.children[1] ? boxForType.children[1].style.border = '1px solid #fff' : console.log('boxForType.children[1] dosen\'t exist for this post');
next.addEventListener('click', () => {
if(card !== undefined){
card.remove();
}
})
})
// Second next eventlistener
next.addEventListener('click', () => {
fetch(`http://localhost:1337/pokemon?page=${pokemonObj.next.page++}&limit=20`)
.then(response => response.json())
.then(data => {
data.result.map(dataEl => {
let main = document.querySelector('main');
let card = document.createElement('div');
if(card !== undefined){
card.remove();
}
let imgHolder = document.createElement('div');
let img = document.createElement('img');
let infoHolder = document.createElement('div');
let infoBoxOne = document.createElement('div');
let infoBoxTwo = document.createElement('div');
let pId = document.createElement('p');
let pName = document.createElement('p');
let boxForType = document.createElement('div');
let id = document.createTextNode('id:');
let name = document.createTextNode('name:');
let type = document.createTextNode('type:');
// Info box 1
let infoPId = document.createElement('p');
let infoPName = document.createElement('p');
let infoPType = document.createElement('p');
infoPId.append(id);
infoPName.append(name);
infoPType.append(type);
infoBoxOne.append(infoPId, infoPName, infoPType);
infoBoxTwo.append(pId, pName, boxForType);
// Lägg till klasser
card.classList.add('card');
imgHolder.classList.add('imgHolder');
infoHolder.classList.add('infoHolder');
boxForType.classList.add('boxForType');
img.classList.add('img');
infoHolder.classList.add('infoHolder');
pId.classList.add('id');
pName.classList.add('name');
infoBoxOne.classList.add('infoBoxOne');
infoBoxTwo.classList.add('infoBoxTwo');
img.src = dataEl.sprites.other['official-artwork']['front_default'];
pId.append(`#${dataEl.id}`);
pName.append(dataEl.name);
// Types
dataEl.types.map(pokeType => {
let pokemonType = pokeType.type.name
let pokes = document.createElement('p');
pokes.append(pokemonType)
boxForType.append(pokes);
})
imgHolder.appendChild(img);
card.appendChild(imgHolder)
main.appendChild(card);
infoHolder.append(infoBoxOne)
infoHolder.append(infoBoxTwo)
card.appendChild(infoHolder);
if(card !== undefined){
card.remove();
}
})
})
})
}
}
paginatedApp.paginatedPokemon();
Usually my page looks like this:
Take note of the scroll bar on right most part of the image.
PROBLEM: sometimes the school logo card would appear at the bottom of the page whenever I go back and forth with Home tab and About tab buttons on the left.
There is no consistent count every time I switch between Home and About on whenever the school logo card would appear at the bottom.
it looks like this:
The school logo card would be rendered after the home carousel card
My js code:
const pageContent = document.getElementById('page-content')
handleLogoForm()
//handles form submission for school logo card
function handleLogoForm(){
var logoform = document.getElementById('logo-form')
logoform.addEventListener('submit', function(e){
e.preventDefault()
let input = document.getElementById('inputGroupFile02');
let data = new FormData();
data.append('image',input.files[0]);
var url = "/web-content/api/changelogo/"
fetch(url,{
method: "POST",
headers: {
"X-CSRFToken": csrftoken,
},
body:data
})
.then((response) => response.json())
.then(function(data){
updateLogo()
e.target.reset()
handleLogoForm.call(this);
logo = document.getElementById('logo-div')
logo.innerHTML = ""
logo.innerHTML = `<img src="${data.image}" alt="no image provided" style="max-width: 7rem; max-height: 7rem;">`
})
})
}
// Getting Home Page Contents
function getLogoCard(){
var url = "http://localhost:8000/web-content/api/changelogo/"
fetch(url)
.then((response) => response.json())
.then(function(data){
// constructing nodes
// create div card parent node
var card = document.createElement('div')
card.classList.add('card')
// cardBody child
var cardBody = document.createElement('div')
cardBody.classList.add('card-body')
var header = document.createElement('h5')
header.innerText = 'School Logo'
var label1 = document.createElement('small')
label1.innerText = 'On display: '
var image = document.createElement('img')
image.src = data[0].image
image.id = 'img'
image.classList.add('card-img-top')
image.style.maxWidth = '10rem'
image.style.maxHeight = '10rem'
var form = document.createElement('form')
form.action = '/web-content/api/changelogo/'
form.method = 'POST'
form.enctype ='multipart/form-data'
form.id ='logo-form'
form.style.display = 'inline'
var csrftokennode = document.createElement('input')
csrftokennode.type = 'hidden'
csrftokennode.value = csrftoken
var inputGroup = document.createElement('div')
inputGroup.classList.add('input-group', 'mb-3')
var imageField = document.createElement('input')
imageField.type = 'file'
imageField.name = 'image'
imageField.classList.add('form-control')
imageField.required = true
imageField.id = 'inputGroupFile02'
var uploadButton = document.createElement('button')
uploadButton.type = 'submit'
uploadButton.classList.add('input-group-text')
uploadButton.for = 'inputGroupFile02'
uploadButton.innerText = 'Upload'
var label = document.createElement('label')
label.for = 'inputGroupFile02'
label.innerText = 'Change:'
// combine elemnts together
card.append(cardBody)
cardBody.append(header)
cardBody.append(label1)
cardBody.append(image)
cardBody.append(document.createElement('br'))
cardBody.append(label)
cardBody.append(form)
form.append(csrftokennode)
form.append(imageField)
form.append(uploadButton)
pageContent.append(card)
handleLogoForm()
})
}
function getCarouselCard(){
var url = "/web-content/api/home-carousel/"
fetch(url)
.then((response) => response.json())
.then(function(data){
var carouselItems = data
// // constructing nodes
var card = document.createElement('div')
card.id = 'carousel'
card.classList.add('card')
var cardBody = document.createElement('div')
cardBody.id = 'card-body'
cardBody.classList.add('card-body')
var header = document.createElement('h5')
header.innerText = 'Home Carousel'
var onDisplay = document.createElement('small')
onDisplay.innerText = 'On display: '
var cardImage = document.createElement('img')
cardImage.classList.add('card-img-top')
cardImage.alt = '...'
cardImage.style.maxWidth = '15rem'
cardImage.style.maxHeight = '15rem'
var cardLabel = document.createElement('small')
cardLabel.innerText = ""
var cardContent = document.createElement('small')
cardContent.innerText = ""
var iconGroup = document.createElement('span')
iconGroup.style.fontSize = '20px'
var trashIconSpan = document.createElement('span')
trashIconSpan.style.color = 'red'
var trashIcon = document.createElement('i')
trashIcon.classList.add('fas', 'fa-trash-alt')
var editIconSpan = document.createElement('span')
editIconSpan.style.color = 'brown'
var editIcon = document.createElement('i')
editIcon.classList.add('far', 'fa-edit')
// construct nodes
card.append(cardBody)
cardBody.append(header)
for (var i = 0; i < data.length; i++) {
cardBody.append(onDisplay)
cardImage.src = data[i].image
cardBody.append(cardImage)
cardBody.innerHTML += '<br>'
cardBody.append(cardLabel)
cardLabel.innerText = data[i].label
cardBody.innerHTML += '<br>'
cardBody.append(cardContent)
cardContent.innerText = data[i].content
cardBody.innerHTML += '<br>'
cardBody.append(iconGroup)
iconGroup.append(trashIconSpan)
trashIconSpan.append(trashIcon)
iconGroup.append(editIconSpan)
editIconSpan.append(editIcon)
cardBody.innerHTML += `<br><hr>`
}
pageContent.append(card)
})
}
// formsssssss
// change logo
function showHomeContent(){
if ( document.getElementById("homeButton").className.match(/(?:^|\s)active(?!\S)/) ){
}else{
document.getElementById('homeButton').classList.add('active')
pageContent.innerHTML = ""
getLogoCard()
getCarouselCard()
}
if ( document.getElementById("aboutButton").className.match(/(?:^|\s)active(?!\S)/) ){
document.getElementById("aboutButton").classList.remove('active')
}
}
function showAboutContent(){
if ( document.getElementById("aboutButton").className.match(/(?:^|\s)active(?!\S)/) ){
return;
}else{
document.getElementById('aboutButton').classList.add('active')
pageContent.innerHTML = ""
pageContent.innerHTML += `
this is about content
`
}
if ( document.getElementById("homeButton").className.match(/(?:^|\s)active(?!\S)/) ){
document.getElementById("homeButton").classList.remove('active')
}
}
the functions that are hooked with Home and About button on the left are showHomeContent() and showAboutContent()
As I mentioned in the comments, you are making two fetch requests that are asynchronous and they are racing to be done first. Whoever wins the race is rendered on top.
So when you fetch the contents, use Promise All
Promise.all([getLogoCard(), getCarouselCard()]).then((values) => {
values.forEach(card => pageContent.append(card));
});
In your functions, return the fetch call, have the fetch return the element you want to append to the document
function getLogoCard() {
...
return fetch(url)
.then((response) => response.json())
.then(function(data){
...
return card;
});
}
I created a todo app to add and remove tasks on the page.
however i would like to keep todo results when browser refreshed .
Is that possible to make this like storing data on db or any storage to save these results?
any idea to make this to save data ??
Now I posted the complete code hereee! because i cant posted code here before
let menu = document.querySelector(".bs");
let btn1 = document.querySelector(".btn");
let btn2 = document.querySelector(".btn3");
let irp = document.querySelector(".date");
let inp = document.querySelector(".input");
let bsd = document.querySelector(".sss");
let brs = document.querySelector(".marker");
let addBr = () => {
btn1.addEventListener("click", addBr);
let br = document.createElement("DIV");
let dd = document.createElement("H1");
dd.innerHTML = (inp.value);
br.className = "red";
var bn = document.createElement("H1");
bn.innerHTML = (irp.value);
menu.appendChild(br);
br.appendChild(dd);
br.appendChild(bn);
if( inp.value == "") {
br.remove();
}
else {
menu.appendChild(br);
}
if( irp.value == "") {
dd.innerHTML = "Albenis";
}
else {
menu.appendChild(br);
}
let ttt = document.createElement("BUTTON");
ttt.className = "marker";
ttt.innerHTML = "Remove";
br.appendChild(ttt);
// This is the important change. Part of creating the .ttt element
// is setting up its event listeners!
ttt.addEventListener('click', () => br.remove());
};
btn1.addEventListener("click", addBr);
// Call `addBr` once to add the initial element
addBr();
<html>
<body>
<div class="bs">
<input type="text" class="input">
<input type="date" class="date">
<button class="btn">
Add
</button>
</div>
</body>
</html>
TL;DR: use localStorage to read the items at page load and write the items when they change, like in the final version
To keep your todo entries, you need to store it in a Database. This can be either a local database in the website like localStorage. Or you need to build a backend which is connected to a Database and send and load the Data from there.
localStorage example:
const items = [{ name: "My Todo" }, { name: "My Todo 2" }];
const setItems = () => {
localStorage.setItem("items", JSON.stringify(items));
};
const getItems = () => {
return JSON.parse(localStorage.getItem("items"));
};
Including your code:
const getItems = () => {
return JSON.parse(localStorage.getItem("items"));
};
const items = getItems() || [];
const setItems = () => {
localStorage.setItem("items", JSON.stringify(items));
};
let addBr = (item) => {
let br = document.createElement("DIV");
let dd = document.createElement("H1");
dd.innerHTML = (item ? item.name : inp.value);
br.className = "red";
var bn = document.createElement("H1");
bn.innerHTML = (item ? item.name : irp.value);
if (!item) {
items.push({ name: inp.value });
setItems();
}
menu.appendChild(br);
br.appendChild(dd);
br.appendChild(bn);
if( inp.value == "") {
br.remove();
}
else {
menu.appendChild(br);
}
if( irp.value == "") {
dd.innerHTML = "Albenis";
}
else {
menu.appendChild(br);
}
let ttt = document.createElement("BUTTON");
ttt.className = "marker";
ttt.innerHTML = "Remove";
br.appendChild(ttt);
// This is the important change. Part of creating the .ttt element
// is setting up its event listeners!
ttt.addEventListener('click', () => br.remove());
};
for (const item of items) {
addBr(item);
}
btn1.addEventListener("click", () => addBr());
The logic seems sound but my ul is not displaying what I am asking it to. I have used console.logs and I am for sure getting poem in the function displayPoem(poem) but it isn't showing up when I button click. Any help would be greatly appreciated!
const inputsList = document.querySelector('ol');
const poemsList = document.getElementById('savedThoughts');
const form = document.getElementById('')
const submitButton = document.getElementById('submitThoughts');
const startButton = document.querySelector('#startButton')
startButton.onclick = () => {
const ranNum = generateRanNum();
generateInputs(ranNum)
changeToRestartText()
}
submitButton.onclick = () => {
const poem = savePoem();
console.log(poem)
displayPoem(poem);
clearForm()
}
const generateRanNum = () => {
let randomNumber = Math.floor(Math.random() * 20);
return randomNumber
}
const changeToRestartText = () => {
startButton.textContent = 'Restart Game'
}
const generateInputs = (ranNum) => {
const listItem = document.createElement('li');
for(let i = 1; i <= ranNum; i++){
const input = document.createElement('input');
listItem.appendChild(input).setAttribute('type', 'text');
console.log(ranNum)
}
inputsList.appendChild(listItem);
}
const savePoem = () => {
let poemArr = [];
const input = document.querySelectorAll('input');
input.forEach(element => {
poemArr.push(element.value);
})
// console.log(poemArr)
return poemArr;
}
const displayPoem = (poem) => {
const savedPoem = document.createElement('li')
const savedText = document.createElement('span')
const deletePoem = document.createElement('button')
console.log(poem)
savedPoem.appendChild(savedText);
savedText.textContent = poem.toString();
savedPoem.appendChild(deletePoem);
deletePoem.textContent = 'Delete';
poemsList.appendChild(savedPoem)
deletePoem.onclick = e => {
poemsList.removeChild(savedPoem);
}
}
const clearForm = () => {
const inputLi = document.querySelectorAll('li');
inputLi.forEach(element => {
element.remove()
})
}
small html segment
<div >
<ul id="savedThoughts">
</ul>
</div>
Your saved list items aren't showing up because your submit onclick calls displayPoem which creates list items and then calls clearForm which removes all list items on the page. Try inputLi = document.querySelectorAll('ol > li').