Cannot read properties of null (reading 'forEach') problem - javascript

I was working on the todo list project, but while transferring the values ​​written to the local storage to the UI, I encountered this error. I tried all the suggestions, but I could not do anything. What should I do?
Here is my code:
const form = document.querySelector("#todo-form");
const todoInput = document.querySelector("#todo");
const todoList = document.querySelector(".list-group");
const firstCard = document.querySelectorAll(".card-body")[0];
const secondCard = document.querySelectorAll(".card-body")[1];
const filter = document.querySelector("#filter");
const clearButton = document.querySelector("#clear-todos");
eventListeners();
function eventListeners() {
form.addEventListener("submit", addTodo);
document.addEventListener("DOMContentLoaded", loadAllTodosToUI);
}
function loadAllTodosToUI() {
let todos = getTodosFromStorage();
todos.forEach(function (todo) {
addTodoToUI(todo)
});
}
function addTodo(e) {
const newTodo = todoInput.value.trim();
if (newTodo === "") {
showAlert("danger", "bir todo gir");
} else {
addTodoToUI(newTodo);
addTodoToStorage(newTodo);
showAlert("success", "başarıyla eklendi");
}
e.preventDefault();
}
function getTodosFromStorage() {
let todos;
if (localStorage.getItem("todos") === null) {
todos = [];
} else {
todos = JSON.parse(localStorage.getItem(todos));
}
return todos;
}
function addTodoToStorage(newTodo) {
let todos = getTodosFromStorage();
todos.push(newTodo);
localStorage.setItem("todos", JSON.stringify(todos));
}
function showAlert(type, message) {
const alert = document.createElement("div");
alert.className = `alert alert-${type}`;
alert.textContent = message;
firstCard.appendChild(alert);
setTimeout(() => {
alert.remove();
}, 1000);
}
function addTodoToUI(newTodo) {
const listItem = document.createElement("li");
const link = document.createElement("a");
link.href = "#";
link.className = "delete-item";
link.innerHTML = "<i class = 'fa fa-remove'></i>";
listItem.className = "list-group-item d-flex justify-content-between";
listItem.appendChild(document.createTextNode(newTodo));
listItem.appendChild(link);
todoList.appendChild(listItem);
todoInput.value = "";
}
The console says that there is an error directly related to forEach, but the value I entered in the local storage is not null, but I get this error

Related

Getting Duplicates on To Do List, yet local storage unaffected

I'm new to javascript and I am trying to use local storage to save user input. With the code as it is right now, I get the user input saved to local storage, but the list does not save when refreshing the page. Also, the user input appends to the to do list multiple times. Thanks for taking a look.
window.addEventListener('load', () => {
const form = document.querySelector('#new-task-form');
const input = document.querySelector('#new-task-input');
const listElement = document.querySelector('#tasks');
todos = JSON.parse(localStorage.getItem('todos')) || [];
console.log(todos)
form.addEventListener('submit', (e) => {
e.preventDefault();
const task = input.value;
if(!task) {
alert('You definitely have something to do...')
return
}
const todo = {
content: task,
id: Math.floor(Math.random() * 100000)
}
todos.push(todo);
localStorage.setItem('todos', JSON.stringify(todos));
todos.forEach(todo => {
const taskElement = document.createElement('div');
taskElement.classList.add('task');
const taskContentElement = document.createElement('div');
taskContentElement.classList.add("content");
taskElement.appendChild(taskContentElement);
const taskInputElement = document.createElement("input")
taskInputElement.classList.add("text");
taskInputElement.type = "text";
taskInputElement.value = task;
taskInputElement.setAttribute('readonly', 'readonly');
taskContentElement.appendChild(taskInputElement);
const taskActionsElement = document.createElement('div');
taskActionsElement.classList.add("actions");
const taskEditElement = document.createElement('button');
taskEditElement.classList.add('edit');
taskEditElement.innerHTML = "Edit";
const taskDeleteElement = document.createElement('button');
taskDeleteElement.classList.add('delete');
taskDeleteElement.innerHTML = "Delete";
taskActionsElement.appendChild(taskEditElement);
taskActionsElement.appendChild(taskDeleteElement);
taskElement.appendChild(taskActionsElement);
listElement.appendChild(taskElement);
input.value = '';
taskEditElement.addEventListener('click', () => {
if (taskEditElement.innerText.toLowerCase() == 'edit') {
taskInputElement.removeAttribute('readonly');
taskInputElement.focus();
taskEditElement.innerText = "Save";
localStorage.setItem("todos", JSON.stringify(todos));
} else {
taskInputElement.setAttribute('readonly', 'readonly');
taskEditElement.innerText = 'Edit';
}
});
taskDeleteElement.addEventListener('click', () => {
todos = todos.filter(t => t != todo);
localStorage.setItem('todos', JSON.stringify(todos));
listElement.removeChild(taskElement);
});
});
});
});
The user input comes up multiple times when added to the list, depending on when added to the array. I was hoping for it to come up one time, and for it to be a normal list.

items saved and get by localstorage as well, but will disappear on page refresh

i have an array named todoList, all of my data is in it.
i saved them to localstorage like this:
https://codepen.io/arashkazerouni/pen/YzLxdoQ
const saveToLocal = (array) => {
window.localStorage.setItem("todo", JSON.stringify(array));
};
todoList = JSON.parse(window.localStorage.getItem("todo"));
i used this saveToLocal function after any change in todoList, and it works.
the only problem is when i refresh the page, all items gone.
but if i add new todo, all of them will shown again
and there is page script :
const input = document.querySelector("input");
const button = document.querySelector("button");
const todos = document.querySelector(".todos");
const alertRed = document.querySelector(".alert-red");
let todoList = [];
const saveToLocal = (array) => {
window.localStorage.setItem("todo", JSON.stringify(array));
};
todoList = JSON.parse(window.localStorage.getItem("todo"));
const addToDOM = () => {
// todos.innerHTML = "";
for (let i = 0; i < todoList.length; i++) {
const html = `
<div class="todo" id=${i}>
<p class="todo-text" >${todoList[i]}</p>
<i class="fa-solid fa-check" ></i>
<i class="fa-solid fa-trash"></i>
</div>
`;
todos.insertAdjacentHTML("beforeend", html);
}
};
// Add items to list
button.onclick = (e) => {
e.preventDefault();
// todos.innerHTML = "";
if (!todoList.includes(input.value) && input.value !== "") {
todoList.push(input.value);
saveToLocal(todoList);
}
// console.log(todoList);
addToDOM();
input.value = "";
};
// Handle Enter Press
document.onkeypress = (e) => {
if (e.key === "Enter") {
button.click();
}
};
todos.onclick = (e) => {
e.preventDefault();
const isCheck = e.target.classList.contains("fa-check");
const isTrash = e.target.classList.contains("fa-trash");
if (isCheck) e.target.previousElementSibling.classList.toggle("checked");
if (isTrash) {
const element = e.target.parentElement;
const elementID = parseInt(element.id);
element.classList.add("removed");
todoList = todoList.filter((element) => element !== todoList[elementID]);
saveToLocal(todoList);
setTimeout(() => {
addToDOM();
}, 300);
}
};

How can i add Local Storage to my todolist?

I am doing some practice javascript exercise. My project look like 'trello' but much soft and simple.
When i writing some notes to input, javscript adding note dynamically but if i refresh the page/chrome, all things gone or lost.
So i wanna apply localstorage on my project. How can i do it.
My Note project: https://codepen.io/daniel_134/pen/NWwYKyK[My Note project]1
var input = document.querySelector('#text-input');
document.querySelector("#ad-note-btn").addEventListener("click", () => {
if (input.value.length > 1) {
// GET-INPUT-VALUE
var getvalue = input.value;
// CREATE-NEW-NOTE
const newLi = document.createElement("textarea");
newLi.value = getvalue;
newLi.className = "note-li";
// ADD-NEW-NOTE
var ul = document.querySelector('#list-items');
ul.appendChild(newLi);
// EMPTY-INPUT-WHEN-CREATING-NEW-NOTES
input.value = " ";
// DELETE-NOTES
const dleLi = document.createElement("button");
dleLi.textContent = "delete";
dleLi.className = "list-btn";
ul.appendChild(dleLi);
dleLi.addEventListener("click", () => {
newLi.remove();
dleLi.remove();
edLi.remove();
saveLi.remove();
})
// EDIT-NOTES
const edit = () => {
if( newLi.value.length > 0 ) {
newLi.disabled = true;
} else {
newLi.disabled = false;
}
}
edit()
const edLi = document.createElement("button");
edLi.textContent = "Edit";
ul.appendChild(edLi);
edLi.className = "list-btn";
edLi.addEventListener("click", () => {
if ( newLi.disabled = true ) {
newLi.disabled = false;
}else {
newLi.disabled = true;
}
})
const saveLi = document.createElement("button");
saveLi.textContent = "save";
ul.appendChild(saveLi);
saveLi.className = "list-btn";
saveLi.addEventListener("click", () => {
edit();
})
} else {
ul.appendChild();
}
})
document.querySelector("#clear-btn").addEventListener("click", () => {
input.value = " ";
})
2
it'll look like that , for example :
when you load your page .
load todoList var todoList = JSON.parse(localStorage.getItem('todo-list'))
and display it
when you add new element to your to-do list
var todoList = JSON.parse(localStorage.getItem('todo-list'));
var new_todo = [{
title:'for example ...',
complete:false
}];
localStorage.setItem('todo-list',JSON.stringify(new_todo));
}else{
todoList.push({
title:'for example ...',
complete:false
});
localStorage.setItem('todo-list',JSON.stringify(todoList));
}

Local storage not deleting data until page is refreshed

I am pretty much new to Javascript and working on this simple ToDo app that uses local storage to persist data. However, the Delete function can only delete from local storage when refreshed the page. What could be causing this bug? I have attached my code below
I tried commenting on the e.preventDefault() on the form but the page kept on reloading when a task is submitted.
// Selectors
const ul = document.querySelector('.todo-list');
const todoContainer = document.querySelector('.todo-container');
const clearButton = document.createElement('button');
clearButton.classList.add('clear-button');
clearButton.textContent = 'Clear all Completed';
const form = document.querySelector('.form');
const taskInput = document.querySelector('.todo-input');
let todoTasks = JSON.parse(localStorage.getItem('todo')) || [];
let id = todoTasks.length + 1;
const createElement = ({ description, completed = true, index }) => {
const todoItem = document.createElement('li');
todoItem.classList.add('todo-list-item');
todoItem.setAttribute('id', index);
todoItem.innerHTML = `
<input type="checkbox" class="check" value="${completed}">
<button class="hidden" name="${index}"></button>
<span class="todo-item">${description}</span>
<button name='eclips'><i class="fas fa-ellipsis-v"></i></button>
<button name='delete'><i class="fas fa-trash"></i></button>
`;
ul.appendChild(todoItem);
todoContainer.appendChild(ul);
todoContainer.appendChild(clearButton);
};
// get each todo task
todoTasks.forEach(createElement);
// Function that add todo
const addTask = (description, completed, ind) => {
const input = taskInput.value;
todoTasks.push({
description: input,
completed: false,
index: ind,
});
localStorage.setItem('todo', JSON.stringify(todoTasks));
return { description, completed, ind };
};
const checkTodo = (e) => {
const lineText = e.target.nextElementSibling.nextElementSibling.nextElementSibling;
if (lineText.style.textDecoration === 'line-through') {
lineText.style.textDecoration = 'none';
} else {
lineText.style.textDecoration = 'line-through';
lineText.classList.toggle('completed');
}
};
// Function that delete todo
const handleDeleteAndCheck = (e) => {
const item = e.target;
if (e.target.classList[1] === 'fa-trash') {
const todo = item.parentElement.parentElement;
const targetId = item.parentElement.parentElement.id;
todoTasks = todoTasks.filter((task) => task.index !== +targetId);
localStorage.setItem('todo', JSON.stringify(todoTasks));
todo.remove();
}
if (e.target.classList === 'check') {
checkTodo();
}
};
// Function that Edit todo
const editTask = (e) => {
const item = e.target;
if (item.classList[0] === 'todo-item') {
item.contentEditable = true;
item.style.display = 'block';
}
};
const check = document.querySelectorAll('.fa-check-square');
const index = document.querySelectorAll('#index');
form.addEventListener('submit', (e) => {
e.preventDefault();
const input = taskInput.value;
const checkValue = check.value;
// const indexValue = index.value;
const newTask = addTask(input, checkValue, id);
createElement(newTask);
// location.reload();
taskInput.value = '';
id += 1;
});
ul.addEventListener('click', handleDeleteAndCheck);
ul.addEventListener('click', editTask);
Here please change the statement with this in your handleDeleteAndCheck() method. It will remove the local storage at that time.
localStorage.removeItem('todo');

Cannot edit my TO-DO List web app using javascript

Edit function in my code isn't working.
I tried a few different methods but ended up getting the same error.
The problem is with the edit function, but I can't figure it out. I am getting the error Uncaught TypeError: edit is not a function".
But I have defined the edit function. I tried adding this, but the edit gave me the same error.
The other functionalities like add and delete are working, but I am not able to edit my list of items. Please suggest a solution.
JSFiddle Link to my code
This is my javascript code :
const todoInput = document.querySelector(".todo-input");
const todoButton = document.querySelector(".todo-button");
const todoList = document.querySelector(".todo-list");
const filterOption = document.querySelector(".filter-todo");
//Event Listeners
document.addEventListener("DOMContentLoaded", getTodos);
todoButton.addEventListener("click", addTodo);
todoList.addEventListener("click", deleteTodo);
filterOption.addEventListener("click", filterTodo);
//Functions
function addTodo(e) {
//Prevent natural behavior
e.preventDefault();
//Create todo div
const todoDiv = document.createElement("div");
todoDiv.classList.add("todo");
//Create list
const newTodo = document.createElement("li");
newTodo.innerText = todoInput.value;
//Save to local - do this last
//Save to local
saveLocalTodos(todoInput.value);
//
newTodo.classList.add("todo-item");
todoDiv.appendChild(newTodo);
todoInput.value = "";
var edit = document.createElement('button');
edit.classList.add('edit');
edit.innerHTML = "EDIT";
edit.addEventListener('click', () => edit(e));
todoDiv.appendChild(edit);
//Create Completed Button
const completedButton = document.createElement("button");
completedButton.innerHTML = `<i class="fas fa-check"></i>`;
completedButton.classList.add("complete-btn");
todoDiv.appendChild(completedButton);
//Create trash button
const trashButton = document.createElement("button");
trashButton.innerHTML = `<i class="fas fa-trash"></i>`;
trashButton.classList.add("trash-btn");
todoDiv.appendChild(trashButton);
//attach final Todo
todoList.appendChild(todoDiv);
}
function edit(e){
const item = e.target;
if(todoInput.disabled == true){
todoInput.disabled = !todoInput.disabled;
}
else{
todoInput.disabled = !todoInput.disabled;
let indexof = todos.indexOf(item);
todos[indexof] = todoInput.value;
window.localStorage.setItem("todos", JSON.stringify(todos));
}
}
function deleteTodo(e) {
const item = e.target;
if (item.classList[0] === "trash-btn") {
// e.target.parentElement.remove();
const todo = item.parentElement;
todo.classList.add("fall");
//at the end
removeLocalTodos(todo);
todo.addEventListener("transitionend", e => {
todo.remove();
});
}
if (item.classList[0] === "complete-btn") {
const todo = item.parentElement;
todo.classList.toggle("completed");
console.log(todo);
}
}
function filterTodo(e) {
const todos = todoList.childNodes;
todos.forEach(function(todo) {
switch (e.target.value) {
case "all":
todo.style.display = "flex";
break;
case "completed":
if (todo.classList.contains("completed")) {
todo.style.display = "flex";
} else {
todo.style.display = "none";
}
break;
case "uncompleted":
if (!todo.classList.contains("completed")) {
todo.style.display = "flex";
} else {
todo.style.display = "none";
}
}
});
}
function saveLocalTodos(todo) {
let todos;
if (localStorage.getItem("todos") === null) {
todos = [];
} else {
todos = JSON.parse(localStorage.getItem("todos"));
}
todos.push(todo);
localStorage.setItem("todos", JSON.stringify(todos));
}
function removeLocalTodos(todo) {
let todos;
if (localStorage.getItem("todos") === null) {
todos = [];
} else {
todos = JSON.parse(localStorage.getItem("todos"));
}
const todoIndex = todo.children[0].innerText;
todos.splice(todos.indexOf(todoIndex), 1);
localStorage.setItem("todos", JSON.stringify(todos));
}
function getTodos() {
let todos;
if (localStorage.getItem("todos") === null) {
todos = [];
} else {
todos = JSON.parse(localStorage.getItem("todos"));
}
todos.forEach(function(todo) {
//Create todo div
const todoDiv = document.createElement("div");
todoDiv.classList.add("todo");
//Create list
const newTodo = document.createElement("li");
newTodo.innerText = todo;
newTodo.classList.add("todo-item");
todoDiv.appendChild(newTodo);
todoInput.value = "";
var edit = document.createElement('button');
edit.classList.add('edit');
edit.innerHTML = "EDIT";
edit.addEventListener('click', () => edit(e));
todoDiv.appendChild(edit);
//Create Completed Button
const completedButton = document.createElement("button");
completedButton.innerHTML = `<i class="fas fa-check"></i>`;
completedButton.classList.add("complete-btn");
todoDiv.appendChild(completedButton);
//Create trash button
const trashButton = document.createElement("button");
trashButton.innerHTML = `<i class="fas fa-trash"></i>`;
trashButton.classList.add("trash-btn");
todoDiv.appendChild(trashButton);
//attach final Todo
todoList.appendChild(todoDiv);
});
} ```
Try renaming the function to "OnEditPress".
You have a variable called "edit" as well as a function called "edit". Try using different names for these.
Assuming you have renamed the method to onEditPress, don't forget to pass the event object to your renamed edit method
edit.addEventListener('click', (e) => onEditPress(e));

Categories