weekly updates
This commit is contained in:
92
posts/career/javascript.org
Normal file
92
posts/career/javascript.org
Normal file
@@ -0,0 +1,92 @@
|
||||
#+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
|
||||
Reference in New Issue
Block a user