Diving in to JavaScript: adding comments, that persist on the DOM

Bams J. Teague
6 min readAug 26, 2021

To say my first experience with JavaScript was tedious, is an understatement. Going from the tight structure of Ruby & Rails in my previous course modules here at Flatiron…really got me at first. Now that I have a better grasp on the subject matter, I want to show you how I got comments to persist to both my backend and on the DOM display in an instagram clone I’m building called Aviangram (basically Instagram for birders).

Getting us started, let’s take a look at the classes I made for my OO-JS and what arguments are getting passed in through the constructor methods.

I start my classes by saving the URL I will be referencing in a constant before the class. It’s much easier to work with and remember as variable than a URL string!

Here in the Post class, I set up a variable to collect all of my Post objects as well as establish a variable for the <div> element which was hard coded into my index.html file. This is where I want to send my posts when they are created, so I’m grabbing it at the top of the class, to use throughout my class. For now, ignore the static getPosts(), we’ll circle back to that function later on.

Here I have my constructor for my Post class which uses ‘this’ to connect the passed in arguments to the class. Aside from it’s attributes that mimic backend, I’ve made sure to send in ‘comments’ to make that available to me as a method call later on. Within the models of my Rails backend, I’ve established relationships like so:

backend models and relationships

I’ve also created a new <div> element called a ‘card’ that I would like groupings of information to live, creating separation of my posts.

Setting up my Comment class went quite similarly to my Post class. The differences being setting a specific URL for fetching my comments as opposed to posts. In the Comments constructor() function, the additional argument we’ll pass in (outside of attributes of Comment) is ‘post’ & same as in the other class, we want this to be available for our use in later functions.

Now that I have the basic setup explained, let’s take a look at where things get started for leaving comments that will persist. In the next image, we’re taking a look into the Post class, to my render() function. This function is called elsewhere in the class, but is responsible for, well, rendering the items we want to the DOM!

this function is from the Post class!

Taking a look at this function, it’s pretty straight forward in how it’s creating and appending elements for a Post to the “card” that keeps these items all together. It’s at our const commentForm declaration that things get a little more difficult. Similar to the other elements that create a postCard, I’ve started by setting my variable to a newly created <form> element. After that is established, I go in and add the rest of the form’s html through the use of commentForm.innerHTML = `` (don’t forget to use back tics to contain the HTML you want to add in to the JS file). Now that my forms exist and will be attached to each new Post, thanks to my render() function being called each time a new post is created, we use: this.comments to establish a post’s comments and then we use a function to iterate over those comments so that each new comment is created with it’s related post_id, the submitted content, and that the comment’s will have their own ids as well. Then, on our established variable, ‘newComment’, I’m calling over a function from my Comment class (renderComment()) to make the submitted comment visible to the user after submission. One of the reasons we passed in ‘post’ in our constructor was to make something like this possible and have it connected to our Posts.

Below this, I’ve done as I have with the other elements in this function and made sure to append the commentForm to the Post’s card and provide it with an event listener that will lead us over to our Comment class with the function createComment().

Here’s where we really take off generating the actual comment object! When my event listener within my Post class’s render() is triggered, so is this function. We pass it the post, to gain access to the post’s id and other attributes, as well as the submitted comment. Establishing that comment contains the right attributes (content and a post_id) I move forward to establishing what kind of call I am making to my server and make sure to convert the return of commentPayload from JSON to a string format.

The next part of the createComment() function is a nice fetch call! here’s were our variable for our URL will come in handy as we pass it and the configured object to the fetch call. Within that fetch call, we take the response (r), transform it into JSON, and then for the comment passed in, we set up a new instance of the Comment class and set it’s attributes. Including ‘post’ here gives us access to the post’s attributes (like id).

The next part is nice and simple, we now want to get that newly generated comment and render it to the post’s card on the DOM using the previously mentioned (and illustrated) renderComment() after the new comment is created.

Index.js

Lastly, let’s take a look back at the getPosts() function I mentioned to ignore earlier. I have Post.getPosts(); set up within my event listener “DOMContentLoaded” that is set up in my Index.js file. This function lives in my Post class, & is responsible for getting a lot of elements for our user to see!

post.js

In this function, we just need to look at the last line of code (you’re a fetching master now! I don’t need to re-explain that to you!). here we have grabbed our new post object, and called a function attachToDom() on it.

post.js

This function calls our render() function needed to show our content on the page. It makes sure that each card of post information gets appended to the div element we hardcoded into our HTML file. There you have it! now our Posts are displaying each with it’s own comment form and displayed comments! Not too hard, huh?

--

--

Bams J. Teague

Full stack program engineer and graduate of Flatiron