JS, SPA, OO, and This
Single Page Application’s (SPA) are prevalent throughout modern web application development. The benefit of a SPA is that the page does not require reloading. This allows the user to interact with the application without virtually any downtime. When implemented correctly, the browser will always have content displayed even if a user click’s on a link on the page. Only a portion of the page will get rendered which provides seamless user interaction with minimal wait time.
As par of the Flatiron School curriculum, I created a SPA using a Rails backend API combined with a vanilla Javascript frontend. The frontend utilizes JS object orientation (OO) in order to organize the code in a useful and structured way. The application I built is called “Gastropoda” and is a simple literary magazine designed to focus on the content of the stories.
The main struggle I went through when building this was related to the context for which I was coding in. Since this was my first time working with object oriented JS, I only knew of the this
keyword. I am familiar with “self” in Ruby, and while this
is similar to “self”, it is different enough that it made avoiding JS errors challenging.
I defaulted to using this
in the beginning of the build. Once errors popped up in the console, I made a change by creating a variable at the top of the method and assigning it to this
, like const self = this
. While this works, it proved to be unnecessary in every method that I did this in. I settled on replacing all of these unnecessary variables by implementing arrow functions instead of classic function declarations.
The beauty of arrow functions (if your needs are the same as mine) is that they do not bind their own this
but simply inherit from the scope of the parent. So if you do not need access to the content for which you are calling this on, arrow functions may be useful.
Another implementation I used to control the context of functions is by using bind
. In the method below, event listeners are set and callback functions are passed in as arguments. Since the callback functions that are passed in are also methods inside this class, the context of these functions would be whatever comes prior to the .addEventListener
. To address this issue, I bind this
to the callback function in order to assign the context.
Another issue that challenged me for awhile was how to pass in an argument to a callback function when you are using .bind
. The last two lines of the method below shows that the argument goes in the .bind
parenthesis, but comes after the first argument of this
.
I also spent a considerable amount of time avoiding making new fetch requests if it wasn’t absolutely necessary. When the app is initially run, the class method Entry.loadEntries()
is invoked. This class is where the majority of the JS code lives. This class has a static method named allEntries
that initially points to an empty array. This array is populated with entry objects when loadEntries()
is called which pushes these new objects into the allEntries
as part of the constructor for instances of Entry
. So from the start, a get
fetch request to the backend is initialized which is the only time a get request for entries is utilized . I configured the data using a serializer so that everything the fetch request returned was all the data I needed for the app. This includes the comment objects associated with an entry (an entry has many comments and a comment belongs to an entry). Because of this, a fetch request for an individual entry is unnecessary since all of the data is turned into Javascript objects and held in an accessible array.
The Final SPA
The Github repository for this application can be found at the link below. Feel free to clone the repo and run the app in your browser to play around with it. Any comments or questions are greatly appreciated!
https://github.com/dougschallmoser/gastropoda-js-app