javascript project: Shoe Collection SPA

Posted by Juny McArdle on January 6, 2020

I finally moved another step closer to becoming a programmer. Throughout my time at Flatiron, I’d enter every project as if it was the most difficult, only to find out the next project would be even harder. However, this javascript project has definitely been the most challenging. Even midway through the project I was still confused and could not understand why I would need certain functions or what some classes do. Hopefully as I go through the process of what I did to complete this application it will better assist with my own understanding javascript because I am having to explain it all to you through my blog entry.

Backend - Rails API

I have two models for this API, the Brand class and Shoe class. Their relationship is based on has_many and belongs_to.

class Brand < ApplicationRecord
    has_many :shoes
end

class Shoe < ApplicationRecord
    belongs_to :brand

    validates :model, :size, :color, :image, presence: true
end

The controllers have some basic CRUD actions render to json.

class Api::V1::BrandsController < ApplicationController
    def index
        @brands = Brand.all

        render json: @brands, status: 200
    end

    def show
        @brand = Brand.find(params[:id])

        render json: @brand, status: 200
    end

    def create
        @brand = Brand.new(brand_params)
        if @brand.save
            render json: @brand, status: 200
        else
            render :new
        end
    end
		
		def destroy
        @brand = Brand.find(params[:id])
        @brand.delete

        render json: {brandId: @brand.id}
    end

    private
    def brand_params
        params.require(:brand).permit(:name, :image)
    end

end

This APP uses Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possible.

gem 'rack-cors'

AJAX stands for Asynchronous JavaScript and XML. AJAX is a new and popular technique for creating more dynamic and interactive web applications with the help of XML, HTML, CSS, and Java Script.

Frontend

HTML

This app starts the page with the basic elements of HTML. Head consists of the style links and the script links to all the files. The Body contains the brand logo images and a form to add new shoes. The javascript function creates more elements and the user’s action(s) determine what HTML is changed and what will be displayed on the page.

<div id="new-shoe-container">
      <form id="new-shoe-form">
        <h3>Add a new shoe</h3>
        Brand:
          <select name="brand_id" id="shoe-brand-name" form="new-shoe-form">
            
          </select>
        Model: <input type="text" name="model" id="new-shoe-model">
        Size: <input type="text" name="size" id="new-shoe-size">
        Color: <input type="text" name="color" id="new-shoe-color">
        Category:
          <select name="category" id="new-shoe-category" form="new-shoe-form">
            <option value="Boots">Boots</option>
            <option value="Heels">Heels</option>
            <option value="Sneakers">Sneakers</option>
            <option value="Trainers">Trainers</option>
            <option value="Sandals">Sandals</option>
            <option value="Wedges">Wedges</option>
            <option value="Flats">Flats</option>
          </select>
        Image: <input type="text" name="image" id="new-shoe-image">
        <button type="submit" class="btn btn-primary">Save</button>
          </form>
    <br>
</div>

CSS

I’m a novice with incorporating CSS to create more stylish and interactive pages, but I really enjoy this element of programming because I previously attended school for Graphic Design. Color, font style, and layout selection are a fun part of the design process and I hope to become more knowledgeable and skilled so that I can take advantage of using CSS in future applications.

button {
  font-size: 15px;
  display: inline-block;
  border: 1px solid rgb(155, 152, 152);
  padding: 0 10px;
  border-radius: 10px;
  text-decoration: none;
  height: 30px;
  line-height: 5px;
  margin-top: 20px;
  cursor: pointer;
  font-weight: 300;
  margin-top: 15px;
}

button:hover {
    border: 1px solid rgb(250, 247, 249);
    background-color: rgb(248, 169, 176);
    color: white;
}

Javascript

Javascript is the primary code used to display all the elements and functionalities that alter the page based on the user’s action. It fetches all the data from the json that is rendered by rails on the backend. It was difficult to understand the connection between both front and backend, distinction of the different classes in the files. I had to understand how all these connections took place on both sides.

For purpose of explaination, the App class receives and reads information then distributes it to the BrandSelectorclass and DisplayManager class. These classes create the brand and shoe then render them to display, send POST requests, as well as DELETE requests to the backend through the adapters.

class BrandSelector {
    constructor() {
        this.brands = []
        this.bindingsAndEventListeners()       
        this.selectedBrand = null
    }

    bindingsAndEventListeners() {
        this.container = document.querySelector('#brand-container')
        this.allBrandsContainer = document.getElementById("all-brands")
        this.image = document.getElementsByTagName('img')

        this.allBrandsContainer.addEventListener('click', this.selectBrandLogo.bind(this))
    }
	}
	
	class DisplayManager {
    constructor() {
        this.shoes = []
        this.selectedBrand = null
        this.bindingsAndEventListeners()
    }

    async fetchAndRenderShoes() {
      
        try {
            console.log(this.selectedBrand)
            const brandId = this.selectedBrand.id
            this.shoes = await Shoe.retrieveByBrand(brandId)
            this.renderShoes()
        }catch(err) {
            alert(err)
        }
        
    }
}

The BrandAdapter and ShoeAdapter will request POST and DELETE then fetch all the data from the backend based on baseURL(http://localhost:3000/api/v1). This was the most complicated part of the project and I had to repeatedly refer back to Cernan and Micah’s videos. Every time I wanted to add additonal functionalities I would have to constantly code back and forth between those files causing me to get lost in the process.

class BrandAdapter {

        get baseURL() {
            return  `http://localhost:3000/api/v1`
        }

        get brandsURL() {
            return `${this.baseURL}/brands`
        }

        brandURL(id) {
            return `${this.brandsURL}/${id}`
        }

        get headers() {
            const stdHeader = {
                'Content-Type': 'appliaction/json',
                'Accept': 'application/json'
            }
            return stdHeader
        }
				
			async newBrand(params) {
            const res = await fetch(this.brandsURL,{
                method: 'POST',
                headers: this.headers,
                body: JSON.stringify(params)
            })
            this.checkStatus(res)
            return await res.json()
        }
}

Around the time I added the function to delete a shoe, I was able to connect the code between files and the backend without any assistance. This made me really proud to finally make it all work. There were still some small issues I came across that I needed help with, but for the most part I was able to to complete it solo and that was such a great feeling.

Conclusion

There was a moment I was depressed and uncertain of continuing to become a programmer. I doubted my ability to complete this course or that I had the necessary talent to be a successful programmer. However, through each project I’ve had this come across my mind and I continued to overcome these challenges. I found out that I was actually on the right track and I was only making minor mistakes that were causing all this unnecessary frustration. What I’ve come to realize is that it is okay to make mistakes especially in programming. These mistakes are what require you to dig deep, find the problem, analyze, and form a solution. The basic steps that have made me become a better programmer.