2.6 KiB
Understands the Javascript language
JS - Competency Log
To evidence this competency I wanted to use a comment system that I implemented for my website. The goal was to fetch comments from an API, render them dynamically and support nested replies.
Working with the DOM
A key part of front end JS development is manipulating the DOM (Document
Object Model). I dynamically created comment elements using
document.createElement rather than injecting raw HTML. This approach
avoids security issues such as cross-site scripting (XSS).
As an example:
const wrapper = document.createElement("div");
wrapper.className = "comment";
const author = document.createElement("strong");
author.textContent = comment.author || "Anonymous";
Using textContent ensures that any user submitted content is safely rendered as text instead of HTML.
Data structures
Comments returned from the backend are stored as a flat array, but replies must be displayed as a nested tree structure. To solve this, I implemented the buildCommentTree function.
const byId = {};
const roots = [];
I use the JS object byId as a lookup table (O(1) complexity) to access
comments by ID. This ensures that I can quickly find the parent of a
comment. I then use the roots array to store the top-level comments,
which are the ones without a parent ID.
const parent = byId[comment.parent_id];
if (parent) parent.children.push(comment);
Async programming
Modern front-end applications frequently communicate with APIs. I used async/await to handle asynchronous operations when fetching and posting comments.
async function fetchComments() {
const res = await fetch(`/api/comments/${pageSlug}`);
return await res.json();
}
I used async/await instead of promise chaining to make the code more readable and easier to understand. I also added some response validations:
if (!res.ok) {
console.error("Failed to fetch comments");
}
Event Handling
JS event handling was used to respond to user interactions, such as submitting a comment or replying.
form.addEventListener("submit", async event => {
event.preventDefault();
Calling preventDefault() prevents the browser from reloading the page during form submission, allowing the comment system to update dynamically instead.
Also the same for replies:
replyBtn.onclick = () => showReplyForm(wrapper, Number(comment.id));