I am making a code journal to write down entries on a virtual journal and make them viewable, editable, and deletable. The error I am getting is:
main.js:71 Uncaught Error: No entries or entry list!
at toggleNoEntries (main.js:71:15)
at HTMLFormElement.<anonymous> (main.js:28:5) .
Can someone tell me what I am missing or doing wrong?
HTML: HTML:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Code Journal</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">Code Journal</h1>
<div>
<a href="#" id="entries-link">Entries</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">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="Image preview"
class="url-preview" />
</div>
<div class="column-half">
<div class="input">
<label for="title">Title</label>
<input type="text" id="title" required />
</div>
<div class="input">
<label for="photo-url">Photo URL</label>
<input type="url" id="photo-url" required />
</div>
</div>
</div>
<div class="row">
<div class="column-full">
<label for="content">Notes</label>
<textarea id="content" cols="30" rows="10" required></textarea>
</div>
</div>
<div class="row">
<div class="column-full button-container">
<button type="submit">SAVE</button>
</div>
</div>
</form>
</div>
<div data-view="entries" class="hidden">
<div class="row">
<div class="column-full entries-heading">
<h1>Entries</h1>
<p class="no-entries">No entries</p>
<a href="#" id="new-entry-button" class="new-entry-button">NEW</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 query failed!');
if (!$urlPreview) throw new Error('$urlPreview query failed!');
if (!$photoUrlInput) throw new Error('$photoUrlInput query failed!');
$photoUrlInput.addEventListener('input', function (event: Event) {
const target = event.target as HTMLInputElement;
$urlPreview.src = target.value || '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 = '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 query has failed!');
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('No entries!');
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('View elements not found!');
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 query failed!');
$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 query failed!');
$newEntryButton.addEventListener('click', function (event: Event) {
event.preventDefault();
viewSwap('entry-form');
});
I don’t need $entryList, but if I were to delete it, I would lose the content of the title and notes of when I press the entries button inside of the header. Could it also be something wrong I did in my html?