Не удается создать запись или просмотреть список записей в Кодовом журнале.

Вопрос или проблема

Не удается создать запись или просмотреть список записей в Кодовом журнале.

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

main.js:71 Uncaught Error: No entries or entry list!
at toggleNoEntries (main.js:71:15)
at HTMLFormElement.\<anonymous\> (main.js:28:5) .
Может кто-то сказать, что я пропустил или сделал неправильно?

HTML:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Журнал кода</title>
    <link rel="stylesheet" href="css/reset.css" />
    <link rel="stylesheet" href="css/layout.css" />
    <link rel="stylesheet" href="css/styles.css" />
  </head>
   <body>
    <header>
      <div class="container">
        <div class="row">
          <div class="column-full navbar">
            <h1 class="code-journal">Журнал кода</h1>
            <div>
              <a href="#" id="entries-link">Записи</a>
            </div>
          </div>
        </div>
      </div>
    </header>
    <main class="container">
      <div data-view="entry-form">
        <div class="row">
          <div class="column-full">
            <h1 class="new-entry">Новая запись</h1>
          </div>
        </div>

        <form id="entry-form">
          <div class="row">
            <div class="column-half">
              <img
                id="url-preview"
                src="/images/placeholder-image-square.jpg"
                alt="Предпросмотр изображения"
                class="url-preview" />
            </div>
            <div class="column-half">
              <div class="input">
                <label for="title">Название</label>
                <input type="text" id="title" required />
              </div>
              <div class="input">
                <label for="photo-url">URL изображения</label>
                <input type="url" id="photo-url" required />
              </div>
            </div>
          </div>
          <div class="row">
            <div class="column-full">
              <label for="content">Заметки</label>
              <textarea id="content" cols="30" rows="10" required></textarea>
            </div>
          </div>
          <div class="row">
            <div class="column-full button-container">
              <button type="submit">СОХРАНИТЬ</button>
            </div>
          </div>
        </form>
      </div>
      <div data-view="entries" class="hidden">
        <div class="row">
          <div class="column-full entries-heading">
            <h1>Записи</h1>
            <p class="no-entries">Нет записей</p>
            <a href="#" id="new-entry-button" class="new-entry-button">НОВАЯ</a>
          </div>
        </div>
        <ul class="entry-list"></ul>
      </div>
    </main>
    <script src="js/data.js"></script>
    <script src="js/main.js"></script>
  </body>
</html>

Typescript:

const $form = document.querySelector('#entry-form') as HTMLFormElement;
const $urlPreview = document.querySelector('#url-preview') as HTMLImageElement;
const $photoUrlInput = document.querySelector('#photo-url') as HTMLInputElement;

if (!$form) throw new Error('$form запрос не удался!');
if (!$urlPreview) throw new Error('$urlPreview запрос не удался!');
if (!$photoUrlInput) throw new Error('$photoUrlInput запрос не удался!');

$photoUrlInput.addEventListener('input', function (event: Event) {
  const target = event.target as HTMLInputElement;
  $urlPreview.src = target.value || "https://stackoverflow.com/questions/79009095/images/placeholder-image-square.jpg";
});

$form.addEventListener('submit', function (event: Event) {
  event.preventDefault();

  const newEntry = {
    entryId: data.nextEntryId,
    title: ($form.elements.namedItem('title') as HTMLInputElement).value,
    photoUrl: $photoUrlInput.value,
    content: ($form.elements.namedItem('content') as HTMLTextAreaElement).value,
  };
  const $newEntryElement = renderEntry(newEntry);
  const $entryList = document.getElementById('entry-list');

  if ($entryList && $newEntryElement) {
    $entryList.appendChild($newEntryElement);
  }

  toggleNoEntries();

  data.nextEntryId++;
  data.entries.unshift(newEntry);

  writeData();

  $form.reset();
  $urlPreview.src="https://stackoverflow.com/questions/79009095/images/placeholder-image-square.jpg";
});

function renderEntry(entry: JournalEntry): HTMLElement {
  const $li = document.createElement('li');
  $li.classList.add('row');

  const $imgWrapper = document.createElement('div');
  $imgWrapper.classList.add('column-half');

  const $img = document.createElement('img');
  $img.src = entry.photoUrl;
  $img.alt = `${entry.title}`;
  $img.classList.add('url-preview');

  const $div = document.createElement('div');
  $div.classList.add('column-half');

  const $h2 = document.createElement('h2');
  $h2.textContent = entry.title;

  const $p = document.createElement('p');
  $p.textContent = entry.content;

  $li.appendChild($imgWrapper);
  $li.appendChild($div);
  $div.appendChild($h2);
  $div.appendChild($p);

  return $li;
}

document.addEventListener('DOMContentLoaded', function () {
  const $ul = document.querySelector('ul');
  if (!$ul) throw new Error('$ul запрос не удался!');

  data.entries.forEach((entry) => {
    const entryElement = renderEntry(entry);
    $ul.appendChild(entryElement);
  });
});

function toggleNoEntries(): void {
  const $noEntries = document.getElementById(
    'no-entries',
  ) as HTMLParagraphElement;
  // const $entryList = document.getElementById('.entry-list');

  if (!$noEntries) throw new Error('Нет записей!');

  if (data.entries.length === 0) {
    $noEntries.style.display = 'block';
  } else {
    $noEntries.style.display = 'none';
  }
}

function viewSwap(view: 'entries' | 'entry-form'): void {
  const $entriesView = document.querySelector(
    '[data-view="entries"]',
  ) as HTMLElement;
  const $entryFormView = document.querySelector(
    '[data-view="entry-form"]',
  ) as HTMLElement;

  if (!$entriesView || !$entryFormView)
    throw new Error('Элементы вида не найдены!');

  if (view === 'entries') {
    $entriesView.classList.remove('hidden');
    $entryFormView.classList.add('hidden');
  } else if (view === 'entry-form') {
    $entryFormView.classList.remove('hidden');
    $entriesView.classList.add('hidden');
  }

  data.view = view;
}

const $entriesLink = document.getElementById(
  'entries-link',
) as HTMLAnchorElement;

if (!$entriesLink) throw new Error('$entriesLink запрос не удался!');

$entriesLink.addEventListener('click', function (event: Event) {
  event.preventDefault();
  viewSwap('entries');
});

const $newEntryButton = document.getElementById(
  'new-entry-button',
) as HTMLAnchorElement;

if (!$newEntryButton) throw new Error('$newEntryButton запрос не удался!');

$newEntryButton.addEventListener('click', function (event: Event) {
  event.preventDefault();
  viewSwap('entry-form');
});

Мне не нужен $entryList, но если я его удалю, я потеряю содержимое заголовка и заметок, когда нажимаю кнопку записей в заголовке. Может быть, это тоже что-то неправильное в моем html?

Ответ или решение

Проблема, с которой вы столкнулись, обусловлена тем, что в коде отсутствует правильная идентификация элемента списка записей, а также может быть неправильное обращение к некоторым элементам в функции toggleNoEntries. Рассмотрим это более подробно.

Ошибка

Исходя из текста ошибки:

Uncaught Error: No entries or entry list!

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

Решение

  1. Проверьте идентификаторы HTML-элементов: Убедитесь, что элементы с идентификатором entry-list и no-entries действительно существуют в разметке HTML. В вашем HTML-коде элемент с классом no-entries имеет следующий код:

    <p class="no-entries">No entries</p>

    Однако, вы обращаетесь к элементу с ID no-entries в коде JavaScript. Измените его на класс:

    const $noEntries = document.querySelector('.no-entries') as HTMLParagraphElement;
  2. Исправление выборки элементов: Попробуйте обновить выборку для entry-list:

    const $entryList = document.querySelector('.entry-list') as HTMLUListElement;
  3. Обновление функции toggleNoEntries: Убедитесь, что ваша функция toggleNoEntries корректно работает с элементом no-entries (или noEntries):

    function toggleNoEntries(): void {
     const $noEntries = document.querySelector('.no-entries') as HTMLParagraphElement;
     const $entryList = document.querySelector('.entry-list') as HTMLUListElement;
    
     if (!$noEntries) throw new Error('No entries paragraph not found!');
    
     if (data.entries.length === 0) {
       $noEntries.style.display = 'block';
       $entryList.style.display = 'none'; // Скрыть список записей
     } else {
       $noEntries.style.display = 'none';
       $entryList.style.display = 'block'; // Показать список записей
     }
    }
  4. Проверка данных: Убедитесь, что объект data правильно инициализирован, и data.entries существует. Это может быть начальным значением, например:

    const data = {
     entries: [],
     nextEntryId: 1,
     view: 'entry-form',
    };
  5. Обработка событий: Добавьте вызов toggleNoEntries() в нужные места, чтобы он обновлялся каждый раз, когда вы добавляете новую запись или переключаетесь между видами.

Полный пример

Для лучшего понимания, вот исправленная версия вашей функции toggleNoEntries и добавленный код для получения элемента списка:

function toggleNoEntries(): void {
  const $noEntries = document.querySelector('.no-entries') as HTMLParagraphElement;
  const $entryList = document.querySelector('.entry-list') as HTMLUListElement;

  if (!$noEntries || !$entryList) throw new Error('Required elements not found!');

  if (data.entries.length === 0) {
    $noEntries.style.display = 'block';
    $entryList.style.display = 'none';
  } else {
    $noEntries.style.display = 'none';
    $entryList.style.display = 'block';
  }
}

Эти шаги должны помочь вам устранить проблему и успешно работать с вашим виртуальным журналом записей. Убедитесь, что все идентификаторы и классы соответствуют объявленным в HTML-коде, а также проверяйте наличие доступных элементов перед их использованием в JavaScript.

Оцените материал
Добавить комментарий

Капча загружается...