Files
org_web/posts/career/javascript.org
2026-03-19 17:59:15 +00:00

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));