#+TITLE: Understands the Javascript language
#+OPTIONS: num:nil
#+DATE: <2026-03-11 Wed 16:52>
#+filetags: :learning:notes:
#+WIP: 
#+COMMENTS: t
#+SLUG: 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:

#+begin_src js
const wrapper = document.createElement("div");
wrapper.className = "comment";

const author = document.createElement("strong");
author.textContent = comment.author || "Anonymous";
#+end_src

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.

#+begin_src js
const byId = {};
const roots = [];
#+end_src

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.

#+begin_src js
const parent = byId[comment.parent_id];
if (parent) parent.children.push(comment);
#+end_src

** Async programming
Modern front-end applications frequently communicate with APIs. I used
async/await to handle asynchronous operations when fetching and posting
comments.

#+begin_src js
async function fetchComments() {
  const res = await fetch(`/api/comments/${pageSlug}`);
  return await res.json();
}
#+end_src

I used async/await instead of promise chaining to make the code more
readable and easier to understand. I also added some response
validations:

#+begin_src js
if (!res.ok) {
  console.error("Failed to fetch comments");
}
#+end_src

** Event Handling
JS event handling was used to respond to user interactions, such as
submitting a comment or replying.

#+begin_src js
form.addEventListener("submit", async event => {
  event.preventDefault();
#+end_src

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:

#+begin_src js
replyBtn.onclick = () => showReplyForm(wrapper, Number(comment.id));
#+end_src
