Building- Single Page Application Project in Vanilla JavaScript

Saloni Mehta
7 min readJun 15, 2021

Before I started my first Single Page Application project in JavaScript, my perception of a SPA(Single Page Application) was that you can not add much to it and that you can’t navigate through much on a single page. To my surprise, that thought process didn’t last long when I started to build my project.

Creating a Single Page Application can be a very creative process in itself, lots of reasoning is done to know how you can add functionality to build the project of your dreams. Even before starting the first steps of Project building (which includes thinking ideas or starting blank), a person should know a few things, which can change the whole envisioning process.

let’s start with what is a Single Page Application (SPA)?

A Single Page Application is a web app that loads only a single web document and then updates the body content of that single document via JavaScript APIs such as XMLHttpRequest and Fetch when different content is to be shown.

Src: https://developer.mozilla.org/en-US/docs/Glossary/SPA

In other words, you are working with only one HTML file and no redirects to another page in a SPA. so you may have an HTML file, one JS file, and a CSS file to style your project.

I will share bits of my project as examples throughout & I coded my project in Visual Studio

File Structure

So this is all we are working with here, NOTE:- db.json here is not required for your project but you can use that to add more functionality to your project, db.json is a database completely in JSON. The database, queries, and results are all JSON data and to use it we need a mock JSON server installed attached is the Github link by @typicode on how it can be set up src:- https://github.com/typicode/json-server

And that’s all we need to start with our project building process, now that we know what we will need to build a SPA. One of the most important tips I would like to share that can add so much to one’s project

<body>  <div id= “mainContainer”><div> </body>

In this example, we have created in our HTML a div where we want to append our contents(content stored in other tags), we can get the our mainContainer using one of the query methods in our JS file for eg in this case:-

const mainContainer = document.getElementById("mainContainer");

now when we are referring to mainContainer we are referring to our main div where i want to append all the contents. The trick here is for example, if i add a link using anchor tag to my div, once i click on the link, i want it to show me the contents of that anchor tag only (note: you can add a-lot of things to anchor tag by using an event listener) i will need to create an event listener on my anchor tag that which it is clicked to show me the contents that i will add to the page without redirecting me to another page so i will make a.href=#because i don’t want it to redirect me to any other link but the most important tip is how can you mimic that you are navigating to a different page but in reality you are not

mainContainer.innerHTML="";

this is it!, here’s our life saver this is basically setting our main div to empty out the existing contents and load new contents with added event listener, you can do this with buttons, links however you like, this will make it look like you are navigating to different pages.

if you do not prefer to use innerHTML no worries, there are other different ways you can achieve the same results.

while (mainContainer.firstChild) {
mainContainer.removeChild(mainContainer.firstChild)}

or

mainContainer.querySelectorAll(“*”).forEach(el => el.remove())

since all of these methods achieve the same results, one can possibly also be better than the other performance wise.

Tip # 2 is when you working with a SPA, you most likely have to use an API, if you are starting new you can start with free APIs and or make a Fake REST API using mock Json server, instructions discussed above on how to make your own.

if you are working with one of the free API’s or paid API, they may look something like this

don’t be scared when you first look at them, best way to read the contents(in JSON) is with using our another life saver fetch() on our beloved console on a browser.

The fetch() function retrieves data. It's a global method on the window object. Want to learn more on fetch ? src : https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API

Basic fetch() request looks something like this:-fetch('http://example.com') //your api's URL
.then(response => response.json())
.then(data => console.log(data));

Using fetch() multiple things can be achieved, you can add data if you are using your own REST API , you can retrieve contents, you can post/ update the data, you can delete the contents. it’s a very useful tool.

For my project, i used a free API, src:- https://makeup-api.herokuapp.com/api/v1/products.json 

I built an Online shopping website Experience for makeup products, this API had some issues with images or the prices of some of the brands so i decided to pick only the brands that have the prices listed and those had the images i liked, so i picked few brands and filter the API by using their brand names and to do that i created a function that only selects the few brands

function fetchSelectedBrands()
{
const brands=[“nyx”,”maybelline”,”clinique”,”milani”];
brands.map((brands)=>{
fetch(`${baseURL}${brands}`)
.then(resp=>resp.json())
.then(product=>displayData(product))
})
}fetchSelectedBrands();

In my function i created an array that stored my brand names and then i used built in method map to check for each array's elements to be string interpolated to my URL and only fetches those brand names since my base URL is https://makeup-api.herokuapp.com/api/v1/products.json?brand=” the brands names are stored after this URL to just get the listed brand names. It’s very interesting to me how useful fetch method is and different ways you can use it.

Now that we know, how these main concepts work when you building the project, let’s talk about how i used them in my website and how i implemented those ideas, i will share pictures of my website now

you can click on individual product type to just shop for that category

This website works just like how an actual shopping site would work, you can add stuff to cart or delete from cart, you can do checkout & you can click on a product to look at it’s description and leave reviews for that product.

it was a really fun project for me to make because i love Online Shopping and of course my first project for my Flatiron School just had to be dedicated to that.

Cart is empty message when there are no items added to the cart

once you click on cart after adding products, you can either delete items from the cart or you can place order for an item. let’s see how that would look like if i delete an item as it should, it will keep me on the same page. To delete the item i use DELETE fetch request to delete that item from the cart database

now that i have deleted one item, i can either place order for an item or delete them from my cart as well

page when i click on place order for that item

when i will click on back to cart it is bringing me to my cart with one item left in there or i can click on continue shopping and that will bring to my home page, NOTE:- all of this is being done only on one HTML file so there are no directs and i am using mainContainer.innerHTML="" to make my page empty and use fetch the GET data/ or POST when the event listeners for those buttons get triggered.

another thing as i previously mentioned you can click on individual products and leave reviews if you like or you can also add item directly to the cart on that

i have POST FETCH request for the reviews and for the add to cart to db.json and for DELETE FETCH request for delete from cart and place order.

This is just one kinds of project you can make if you like, but there are so many other types of SPA that can be build for eg; games. There are so many other features, that can be added when we are working with a website like this, even though with a single page it can be limited sometimes but as you can see there are ways to work around it and have fun with it. :)

--

--