How do I display every element from my localStorage item? - javascript

i'm trying to create a simple To-do list, and my question is how do i get all elements of a single item in localStorage displayed?
pushing things into localStorage in a form of an array works fine, but only thing I see on my page is the first index of the "tasks" array.
const inputEl = document.getElementById("inputEl")
const submitBtn = document.getElementById("submit")
const clearBtn = document.getElementById("clearBtn")
const todoListContainer = document.getElementById("todoList")
const taskContainer = document.querySelector(".task")
const cancelBtn = document.querySelector(".cancelBtn")
const doneBtn = document.querySelector(".doneBtn")
const errorMsg = document.querySelector(".error")
let localStorageContent = localStorage.getItem("tasks")
let tasks = []
function createTask(){
if(inputEl.value.length != 0){
const newDiv = document.createElement("div")
newDiv.classList.add("task")
const newParagraph = document.createElement("p")
const newCancelBtn = document.createElement("button")
newCancelBtn.classList.add("cancelBtn")
newCancelBtn.textContent = "X"
const newDoneBtn = document.createElement("button")
newDoneBtn.classList.add("doneBtn")
newDoneBtn.textContent = "Done"
todoListContainer.appendChild(newDiv)
newDiv.appendChild(newParagraph)
newDiv.appendChild(newCancelBtn)
newDiv.appendChild(newDoneBtn)
//^^ Creating a container for a new task, with all its elements and assigning the classes^^
tasks.push(inputEl.value)
localStorage.setItem("tasks", JSON.stringify(tasks))
inputEl.value = ""
newParagraph.textContent = JSON.parse(localStorageContent)
errorMsg.textContent = ""
}else{
errorMsg.textContent = "You have to type something in!"
errorMsg.classList.toggle("visibility")
}
}
submitBtn.addEventListener("click", () =>{
createTask()
})

When you execute JSON.parse(localStorageContent) you convert your string into an array, that's right.
But:
newParagraph.textContent = JSON.parse(localStorageContent)
is the same as:
newParagraph.textContent = JSON.parse(localStorageContent)[0]
So, you have to loop through your JSON.parse(localStorageContent)
array... Therefore, create a new variable:
let tasksItem = JSON.parse(localStorageContent)
and loop on with .forEach method

Related

Having trouble reducing the total in this small todo app

I am having a hard time trying to figure out how to get the the value from every new Li and reduce it (add) to then output to my h2. Can't figure out what I am doing wrong. Any help would be greatly appreciated! Codepen: https://codepen.io/Chasehud26/pen/Poagjwy
I tried to console.log different variables to see if there were any hints of what is going wrong.
const form = document.querySelector("form")
const nameInput = document.querySelector("#name-input")
const priceInput = document.querySelector("#price-input")
const button = document.querySelector("button")
const nameUl = document.querySelector("#item-name")
const priceUl = document.querySelector("#item-price")
const h2 = document.querySelector("h2")
const nameLi = document.createElement("li")
const priceLi = document.createElement("li")
form.addEventListener("submit", function (e) {
e.preventDefault()
let nameVal = nameInput.value
let priceVal = priceInput.value
const nameLi = document.createElement("li")
const priceLi = document.createElement("li")
nameUl.appendChild(nameLi)
nameLi.innerHTML = nameInput.value
priceUl.appendChild(priceLi)
priceLi.textContent = `${priceInput.value}`
showTotals()
})
//TRYING TO ADD TOGETHER ALL THE PRICE VALUES AND THEN PUT IT TO MY H2//
function showTotals() {
const priceList = document.querySelectorAll("li")
for (let priceLists of priceList) {
const total = []
total.push(parseFloat(priceLists.textContent));
const totalMoney = total.reduce(function (total, item) {
total += item;
return total;
}, 0);
const finalMoney = totalMoney.toFixed(2);
h2.textContent = finalMoney;
}
}
You need to have your const total [] array initialized outside of the for loop. also, when you setup your <li> decorators, you need to differentiate between the number and non-number fields, since the way you had it, it was trying to add the text 'li' fields also:
/// truncated for clarity
const nameLi = document.createElement("li")
const priceLi = document.createElement("li")
priceLi.classList.add('num') // <== this line added
//// =================
function showTotals() {
const priceList = document.querySelectorAll("li.num") // added class
const total = [] // <== move this to here
for (let priceLists of priceList) {
total.push(parseFloat(priceLists.textContent));
const totalMoney = total.reduce(function (total, item) {
total += item;
return total;
}, 0);
const finalMoney = totalMoney.toFixed(2);
h2.textContent = finalMoney;
}

The values are not replacing with new values

firstly, when I search for any city it shows the weather correctly, but when I try to search for another city/country It shows the details of the same city that I have searched for before. I think there is something wrong with my JavaScript code. I think the new values that I'm fetching from the API are not getting replaced by the old values.
let enterCity = document.querySelector("#enterCity");
let city = document.querySelector(".city");
let country = document.querySelector(".country");
let temp = document.querySelector(".temp");
let text = document.querySelector(".text");
let inputVal = enterCity.value;
// the base url
let url = `http://api.weatherapi.com/v1/current.json?q=${inputVal}&key=cb58be19d0d2****************`;
fetch(url).then((response) => {
return response.json();
}).then((data) => {
let search = document.querySelector(".search");
search.addEventListener("click", () => {
let container = document.querySelector(".container");
card = document.createElement("div");
card.className = "card";
city = document.createElement("h2");
city.className = "city";
***The problems are with the innerText down below ***
city.innerText = data.location.name;
country = document.createElement("h5");
country.className = "country";
country.innerText = data.location.country;
temp = document.createElement("h4");
temp.className = "temp";
temp.innerText = data.current.temp_c;
span1 = document.createElement("span");
span1.id = "deg";
span1.innerText = "°C"
temp.appendChild(span1);
icon = document.createElement("img");
icon.className = "icon";
icon.src = data.current.condition.icon;
text = document.createElement("h3");
text.className = "text";
text.innerText = data.current.condition.text;
card.appendChild(city);
card.appendChild(country);
card.appendChild(temp);
card.appendChild(icon);
card.appendChild(text);
container.appendChild(card);
Here, I have also cleared the input value
that I'm taking from the user
enterCity.value = "";
});
});
let search = document.querySelector(".search");
search.addEventListener("click", () => {
let enterCity = document.querySelector("#enterCity");
let city = document.querySelector(".city");
let country = document.querySelector(".country");
let temp = document.querySelector(".temp");
let text = document.querySelector(".text");
var inputVal = enterCity.value;
// the base url
let url = `http://api.weatherapi.com/v1/current.json?q=${inputVal}&key=cb58be19d0d2********************`;
fetch(url).then((response) => {
return response.json();
}).then((data) => {
//Do the remaining works here
})
});
The actual problem was already assigned the value of document.querySelector("#enterCity"); when the page loads instead of on click. So value of enterCity was not changing when you click the search button.
Note : If the key you given in the question is your personal API key,
then please try to change it in the console, because it is not good
idea to publish it in the outside.
This is happening beacause you haven't added onchange event listener on your input(enter city).if you don't add onchange event this will take only your inital value.
So add a onchange listener then call fetch api inside of it.
Dummy example -
let entercity=document.querySelector("#entercity");
entercity.addEventListener('change',()=>{
let inputVal=entercity.value;
let url = `http://api.weatherapi.com/v1/current.json?q=${inputVal}&key=cb58be19d0d2476da35134140211107`;
fetch(url).then((res)=>console.log(res))
.catch((err)=>console.log(err));
})

Whenever the page gets reloaded, an item in a list gets duplicated in javascript

I’m a newbie started js like 2 weeks ago.
I have been making a to-do list.
There are key toDos & finished in localStorage.
I want the value in toDos to go to finished, getting class name “done” if I click the finBtn. Also it should move to the bottom.
At first it works. However, every time the page gets refreshed, the stuff in finished gets duplicated.
This problem’s been bothering me for a week.
Thank you for reading.
const toDoForm = document.querySelector(".js-toDoForm"),
toDoInput = toDoForm.querySelector("input"),
toDoList = document.querySelector(".js-toDoList");
const TODOS_LS = "toDos";
const FINISHED_LS = "finished";
const NOTSTART_CN = "notStart";
const DONE_CN = "done";
let toDos = [];
let toDosDone = [];
function saveToDos(){
localStorage.setItem(TODOS_LS, JSON.stringify(toDos));
}
function updateToDos(){
localStorage.setItem(FINISHED_LS, JSON.stringify(toDosDone));
}
function deleteToDo(event){
const btn = event.target;
const li = btn.parentNode;
toDoList.removeChild(li);
const cleanToDos = toDos.filter(function(toDo){
return toDo.id !== parseInt(li.id);
});
toDos = cleanToDos;
saveToDos();
}
function finish(event){
const btn = event.target;
const li = btn.parentNode;
const oldToDos = localStorage.getItem(TODOS_LS);
const parsedOldToDos = JSON.parse(oldToDos);
const btnNum = parseInt(li.id) - 1;
const finishedStuff = parsedOldToDos.splice(btnNum, 1);
finishedStuff[0].class = DONE_CN;
li.classList.add(DONE_CN);
toDos = parsedOldToDos;
toDosDone = finishedStuff;
saveToDos();
updateToDos();
}
function makeToDos(text){
const li = document.createElement("li");
const span = document.createElement("span");
const delBtn = document.createElement("button");
const finBtn = document.createElement("button");
const newId = toDos.length + 1;
delBtn.innerText="❌";
delBtn.classList.add("delBtn");
delBtn.addEventListener("click", deleteToDo);
finBtn.classList.add("finBtn");
finBtn.innerText = "✔";
finBtn.addEventListener("click", finish);
span.innerText = text;
li.id = newId;
li.appendChild(span);
li.appendChild(delBtn);
li.appendChild(finBtn);
toDoList.appendChild(li);
const toDoObj = {
text: text,
id: newId,
class:""
};
toDos.push(toDoObj);
saveToDos();
}
function handleSubmit(event){
event.preventDefault();
const currentValue = toDoInput.value;
makeToDos(currentValue);
toDoInput.value = "";
}
function loadToDos(){
const loadedToDos = localStorage.getItem(TODOS_LS);
const loadedFinToDos = localStorage.getItem(FINISHED_LS);
if(loadedToDos !== null || loadedFinToDos !== null){
const parsedToDos = JSON.parse(loadedToDos);
const parsedFinToDos = JSON.parse(loadedFinToDos);
parsedToDos.forEach(function(toDo){
makeToDos(toDo.text);
});
parsedFinToDos.forEach(function(done){
makeToDos(done.text);
});
} //else
} //ends of loadToDos
function init(){
loadToDos();
toDoForm.addEventListener("submit", handleSubmit);
}
init();
Your localStorage is not cleaning up on page refresh, you should do localStorage.clear(); Each time page load using

Javascript - can't iterate over object in incremental search

I'm very new to javascript/dev so I hope there is a an obvious solution that I've not thought of. My code returns search items from TVMaze.com API. The feature giving me trouble is the incremental search (as a user types in input box, the code returns and displays images by creating a new div and appending images, removing and replacing the an div).
My problem is that on deleting all characters from input box, I receive the error: "Uncaught (in promise) TypeError: shows is not iterable" which I suppose means that there is no object to iterate over? Thanks in advance for any help.
const input = document.querySelector("#query");
input.addEventListener("input", async function (e) {
e.preventDefault();
const searchTerm = e.target.value;
const config = { params: { q: searchTerm } };
const res = await axios.get(`http://api.tvmaze.com/search/shows?`, config);
makeImages(res.data);
clearList();
});
const makeImages = (shows) => {
const div = document.createElement("div");
for (let result of shows) {
if (result.show.image) {
const img = document.createElement("IMG");
img.className += "resultImage";
img.src = result.show.image.medium;
const title = document.createElement("h3");
title.className += "resultTitle";
title.innerText = result.show.name;
const year = document.createElement("h4");
year.className += "score";
year.innerText = result.show.premiered;
var sub = year.innerText.substring(0, 4);
var yearNum = parseInt(sub);
div.append(year);
div.append(img);
div.append(title);
document.body.appendChild(div);
}
if (yearNum <= 2000) {
var retro = document.createElement("h5");
retro.className = "retro";
retro.innerText = "retro";
div.append(retro);
}
}
};
let clearList = () => {
var allImg = document.querySelectorAll("IMG");
if (allImg.length === 0) {
document.createElement("div");
return makeImages();
}
var oldDiv = document.querySelector("div");
oldDiv.remove();
console.log(oldDiv);
};

How to Remove Particular Element from Array in Javascript with a button

I want to be able to press on my trashcan and be able to delete any todo i want. Right now i can only remove the first index off my todo with with the help off splice. Also when i inspect my array in console i want to be able to use true or false. So when i click on my button my object gets removed from my screen and inside off the array in console it should show that my object indeed have been removed and turns into true instead of false( todoIsRemoved: false). here is a link so you can see all off my code: https://jsfiddle.net/marvstarv/tqdzn8bg/.
this is my class:
let p=0;
let allTheToDos = [];
class Todo{
constructor(toDoItem, removedToDo){
this.Id= p ++;
this.toDoItem = toDoItem;
this.removedToDo = removedToDo;
}
}
this is the function i need help with,
function removeTask (){
let liContainer = document.getElementById ("mySection"); // contains my label(checkmark), Li, and trashcan button.
allTheToDos.splice(Todo,1);
liContainer.innerHTML="";
generateHtml();
console.log(allTheToDos);
}
this function is conected to line 64 off my "main.js": deleteButton.addEventListener('click', () =>{removeTask(allTheToDos[i])});
i appriciate all the help, get back to me if anything was unclear.enter code here
I updated your Js file to:
window.onload = function(){
// without this my site keeps realoding when adding a new item
let firstTask = new Todo ('Bädda sängen',false);
let secondTask = new Todo ('Hänga upp tavlorna',false);
let thirdTask = new Todo ('Kick back & realx',false);
// Adding my premade todo's into my Array that has the variable 'allTheToDos'
allTheToDos.push(firstTask);
allTheToDos.push(secondTask);
allTheToDos.push(thirdTask);
// creating a function so that the user can add a new todo
let addButton = document.getElementById('addBtn');
addButton.addEventListener('click',addNewTask);
generateHtml ();
// let checkedLi = document.getElementById('listItem')
// checkedLi.addEventListener('click',)
console.log(allTheToDos);
}
// my puublic
let p=0;
let allTheToDos = [];
class Todo{
constructor(toDoItem, removedToDo){
this.Id= p ++;
this.toDoItem = toDoItem;
this.removedToDo = removedToDo;
}
}
function generateHtml (){
// Creating an Ul for my items
let section = document.getElementById('mySection');
let myUl = document.createElement('ul');
myUl.className = 'listContainer';
section.appendChild(myUl);
// Creating the loop for my premade todo objects
for(i=0; i<allTheToDos.length; i++){
// Create a div wrapper for my li
let myListWrapperItemContainer = document.createElement('div');
myListWrapperItemContainer.className = "listItemsWrapper";
let id = `to_do_${i}`;
myListWrapperItemContainer.id = id;
// Creating Checked button
let checkedIcon = document.createElement('label');
checkedIcon.className = 'checkedIcon listItemsIcon';
checkedIcon.innerHTML = '<i class="fas fa-check"></i>';
//Creating li
let myLi = document.createElement("li");
myLi.classList = "listItem lineTrough";
myLi.id= "listItem";
// Creating delete button
let deleteButton = document.createElement('button');
deleteButton.id ="deleteButton";
deleteButton.className = 'trashCan listItemsIcon';
deleteButton.innerHTML = '<i class="fas fa-trash-alt"></i>';
// OnClick
deleteButton.addEventListener('click', () => {removeTask(id)});
// Adding everything to my html
myListWrapperItemContainer.appendChild(checkedIcon);
myListWrapperItemContainer.appendChild(myLi);
myListWrapperItemContainer.appendChild(deleteButton);
myLi.innerHTML = allTheToDos[i].toDoItem;
myUl.appendChild(myListWrapperItemContainer);
}
}
function addNewTask (stopRefresh){
stopRefresh.preventDefault();
let liContainer = document.getElementById ("mySection");
let inputValue = document.getElementById('textBox').value;
liContainer.innerHTML="";
if (inputValue == ""){
alert("Type in something");
generateHtml();
}
else{
let newInputValue = new Todo (inputValue);
allTheToDos.push(newInputValue);
generateHtml();
}
}
function removeTask (id){
let element = document.getElementById(id);
let index = allTheToDos.findIndex(e => e.toDoItem === element.textContent);
allTheToDos.splice(index,1);
element.parentNode.removeChild(element);
}

Categories