Ошибка неперехваченного типа: Todos равно нулю

#javascript #typeerror

Вопрос:

Я прохожу курс bootcamp на Java-скриптах.

Я попытался следовать инструкциям, но по какой-то причине после очистки фиктивного массива и введения методов анализа и строковой обработки localstorage я получаю неперехваченную ошибку типа, ссылающуюся на переменную в функции визуализации.

Я сравнил свой код с инструкторами, но, похоже, не могу понять, почему его код не представляет той же проблемы.

Мы очень ценим ваше время и рекомендации.

 let todos = []

const filters = {
  searchText: '',
  hideCompleted: false
}

const todosJSON = localStorage.getItem('todos')

if (todosJSON !== null) {
  todos = JSON.parse(todosJSON)
}

const renderTodos = function(todos, filters) {
  const filteredTodos = todos.filter(function(todo) {
    return todo.text.toLowerCase().includes(filters.searchText.toLowerCase())
  })

  filteredTodos = filteredTodos.filter(function(todo) {
    if (filters.hideCompleted) {
      return !todo.completed
    } else {
      return true
    }
  })

  const incompleteTodos = filteredTodos.filter(function(todo) {
    return !todo.completed
  })

  document.querySelector("#todoList").innerHTML = ''

  const summary = document.createElement('h2')
  summary.textContent = `You have ${incompleteTodos.length} todos left`
  document.querySelector("#todoList").appendChild(summary)

  filteredTodos.forEach(function(todo) {
    const p = document.createElement('p')
    p.textContent = todo.text
    document.querySelector("#todoList").appendChild(p)
  })


}

renderTodos(todos, filters)

document.querySelector("#todo-searcher").addEventListener('input', function(e) {
  filters.searchText = e.target.value
  renderTodos(todos, filters)
})

document.querySelector("#textOfTodo").addEventListener('submit', function(e) {
  e.preventDefault()
  todos.push({
    text: e.target.elements.todoText.value,
    completed: false
  })
  localStorage.setItem('todos', JSON.stringify(todosJSON))
  renderTodos(todos, filters)
  e.target.elements.todoText.value = ''
})

document.querySelector("#hide-completed-todos").addEventListener('change', function(e) {
  filters.hideCompleted = e.target.checked
  renderTodos(todos, filters)
}) 
 <h1>Todos</h1>
<input id="todo-searcher" type="text" placeholder="Search for a Todo">
<label>Hide Completed
                    <input id="hide-completed-todos" type="checkbox">
                    </label>
<div id="todoList"></div>
<form id="textOfTodo">
  <input type="text" placeholder="Todo Description" name="todoText">
  <button>Add Todo</button>
</form>

<script src="todo-app.js"></script> 

Версия для инструкторов:

 const renderTodos = function (todos, filters) {
    const filteredTodos = todos.filter(function (todo) {
        const searchTextMatch = todo.text.toLowerCase().includes(filters.searchText.toLowerCase())
        const hideCompletedMatch = !filters.hideCompleted || !todo.completed

        return searchTextMatch amp;amp; hideCompletedMatch
    })

    const incompleteTodos = filteredTodos.filter(function (todo) {
        return !todo.completed
    })

    document.querySelector('#todos').innerHTML = ''

    const summary = document.createElement('h2')
    summary.textContent = `You have ${incompleteTodos.length} todos left`
    document.querySelector('#todos').appendChild(summary)

    filteredTodos.forEach(function (todo) {
        const p = document.createElement('p')
        p.textContent = todo.text
        document.querySelector('#todos').appendChild(p)
    })
}
 

Комментарии:

1. Я начинаю Uncaught TypeError: Assignment to constant variable. . Вы должны использовать let filteredTodos вместо const filteredTodos , это не константа. Также , пожалуйста, предоставьте соответствующий HTML-код (вы можете отредактировать свой вопрос), потому что появляются другие ошибки, поскольку скрипт не может найти #todo-searcher или #todoList , поэтому в настоящее время вашу реальную проблему трудно воспроизвести.

2. отредактировано, я также изменил его, чтобы разрешить filteredtodos, но это, похоже, не решило проблему. Я также добавил версию блока визуализации для инструктора.

3. Пожалуйста, добавьте этот HTML-код не как простой фрагмент кода, а вместо этого в существующий фрагмент стека (нажмите «Редактировать приведенный выше фрагмент» после нажатия кнопки «Редактировать» [вопрос], чтобы вставить в него html).

4. Я интегрировал ваш HTML-код в созданный мной фрагмент. После того, как я прокомментировал часть localStorage (она не работает, потому что фрагменты изолированы, это нормально), я не получаю никаких ошибок. Как ты получаешь свое?

5. А, понял. Он на перезарядке. Так что это связано с частью локального хранилища. Я этим занимаюсь

Ответ №1:

Это простая опечатка. Вы сохраняете это в локальном хранилище :

  localStorage.setItem('todos', JSON.stringify(todosJSON))
 

но todosJSON при запуске имеет значение null, и это сохраняется в LS, поэтому оно всегда будет равно null. Вы хотите сэкономить

 localStorage.setItem('todos', JSON.stringify(todos))