Favourite Parts of Pod

05/03/2024

Code Structure & the Weird "this" in JS

I like to learn by doing, so I started writing a podcast app in order to learn JavaScript. I was learning the ins and outs of JavaScript as I encountered problems in my program, and mostly used the MDN website - I found it to be the best reference.

I'm not very familiar with design patterns, so in writing the app, I was winging it with an idea of object-oriented programming and a vague idea of trying to keep things loosely-coupled. I ended up refactoring the code 2 times - the first time, I created a custom global events system, and the second time I got rid of it because it was getting too complicated. I had this idea in my mind that references between components are bad and events are good, but when I wrote an event system from scratch (objects could register their functions with other objects, and those other objects would run an array of functions when specific things happened), it became too convoluted. When I decided to let components reference each other, I was struggling with how to avoid having two references between the same two components, like if I had parent.child = child, I didn't want to have to also have child.parent = parent, but I did need to reference the parent component from the child. This was for objects where I didn't want the parent to be the actual superclass of the child.

At the same time, I was struggling with how the "this" keyword works in JavaScript, but its weirdness ended up helping me. I still haven't fully wrapped my head around it, but "this" in JavaScript works differently than I'd expected, as someone who originally learned to program in Java. My solution to the problem of how to allow components to reference each other was one of my favourite parts of the code I wrote, because the idea seemed to come out of nowhere (it actually came from a bug in my code), it made me stop hating JavaScript's "this," it was easy to implement, and seems like it would be generally applicable.

Anyway, what I did was use the parent object (inside its own class) to create the child object, and at the same point, attached arrow functions to the child. This gave the child automatic access to the parent because "this" in an arrow function, inside a class, refers to the class's instance, not the object calling the function as I would have expected (and as in a regular anonymous function). I think of it as JavaScript translating "this" to its value when the arrow function is created, instead of keeping "this" in the code of the function until it's run. An example, inside the class PodcastRow, after I've created an associated EpisodeRow:

newEpRow.displayPodInfo = () => {app.displayPodInfo(this)}

Now EpisodeRow has a function it can call in its own class that will refer to its parent PodcastRow.

The same function, written in the following form, wouldn't work because "this" will refer to the EpisodeRow:

newEpRow.displayPodInfo = function(){app.displayPodInfo(this)}

Templating

The other part of my code that I'm especially proud is the part called templates.js. It's just a module where I keep all the HTML for the dynamically generated UI components. It has a variable for each component that points to a function that returns the HTML, which is contained in backticks which are used in JavaScript for template literals. Template literals allow you to write strings that include pieces of code that evaluate to strings - you enclose the code portion within ${}. The functions refer to data properties of the components, and if the data changes, I can call the component's template function to regenerate its HTML. In my implementation, again, "this" wasn't resolving to what I wanted, so I just used JavaScript's bind() function, which allows you to run a function while explicitly specifying the value of "this."

🠜⭪ HOME 🠜⭪ SITEMAP