JS RoR Project
Published: 2021-07-07 19:31:00


This blog is about my latest project here in Flatiron. It was my first experience with JavaScript and I have to say, I like it! This was a challenge to learn, but I now have a newfound appreciation of the language and take pride in being able to write JavaScript like the programmers I look up to.

For this project, I decided I wanted to achieve a few things:

Reinforce old knowledge
Meet the requirements for the project
Push myself

The Problem
A trading card game I play consists of many different pieces and it's hard to keep everything straight. The sheer size of the game intimidates a lot of people. I wanted to implement a solution that would help other people build and rank cards for decks, based on that creature's abilities.

Data Model
An important part about a project is the data model. The model below shows my has_many and belongs_to relationship.


Creatures(parent)	Skill(child)

Rails

I used Active Model Serializers to transfer data with json.

class CreatureSerializer
  include FastJsonapi::ObjectSerializer
  attributes :name, :image, :description, :skills
end


Above you see the attributes name, image, description, likes, and skills for the Creature database.

I also found that in order to render the correct routes I had to make a change in my config>initializers>cors.rb file.
Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins '*'

    resource '*',
      headers: :any,
      methods: [:get, :post, :put, :patch, :delete, :options, :head]
  end
end


This is the final result.
    {
      "id": "4",
      "type": "creature",
      "attributes": {
        "name": "Creature Name",
        "image": "Creature Image",
        "description": "Creature Description",
        "likes": "0",
        "skills": [
          {
            "id": 86,
            "name": "Creature Skill",
            "creature_id": 4,
            "created_at": "2021-06-10T15:20:17.399Z",
            "updated_at": "2021-06-10T15:20:17.399Z"
          }
        ]
      }


JS

I then worked on building my JavaScrpt objects. My main class was Creature as seen below:

class Creature {

    static allCreatures = []

    constructor(creature){
        this.id = creature.id
        this.name = creature.attributes.name
        this.image = creature.attributes.image
        this.description = creature.attributes.description
        this.likes = creature.attributes.likes
        this.skills = creature.attributes.skills
        Creature.allCreatures.push(this)
        this.renderCreature()
    }

    static renderCreatures(creatures){
        card.innerHTML = ""
        for(let c of creatures){
            c.renderCreature()
        }
    }

    static fetchCreatures(){
        fetch(creaturesURL)
        .then(response => response.json())
        .then(creatures => {
            for( let c of creatures.data){
                let newCreatureCard = new Creature(c)
            }
        })
    }


    renderCreature(){
        const creatureLi = document.createElement('li')
        const h2 = document.createElement('h2')
        const img = document.createElement('img')
        const p = document.createElement('p')
        const creaturesSkills = document.createElement('ul')

        const likeCount = document.createElement('p')
        const likeButton = document.createElement('button')

        const deleteButton = document.createElement('button')
        const skillForm = document.createElement('form')
        creatureLi.dataset.id = this.id
        card.appendChild(creatureLi)
        h2.innerText = this.name
        img.src = this.image
        img.width = 200
        p.innerText = this.description
        likeCount.innerText = this.likes
        likeButton.innerText = "Like"
        likeButton.addEventListener("click", this.addLikes)
        deleteButton.innerText = "Delete"
        deleteButton.addEventListener("click", this.deleteCreature)
        skillForm.innerHTML =`
        <input type="text" placeholder="Add Skill">
        <input type="submit">
        `
        skillForm.addEventListener("submit", Skill.createSkill)
        creaturesSkills.dataset.id = this.id
        this.skills.forEach(skill => {
            let newSkill = new Skill(skill)
            newSkill.renderSkill(creaturesSkills)
        })
        creatureLi.append(h2, img, p, creaturesSkills, skillForm, likeCount, likeButton, deleteButton)
    }

    static submitCreature(event){
        event.preventDefault()
        fetch(creaturesURL, {
            method: "POST",
            headers: {
                "Content-Type":"application/json",
                "Accept":"application/json",
            },
            body: JSON.stringify({
                name: enterCreatureName.value,
                image: enterCreatureImage.value,
                description: enterCreatureDescription.value,
                likes: enterCreatureLikes.value
            })
        })
        .then(res => res.json())
        .then(creature => {
            let newCreature = new Creature(creature.data)
            makeACreature.reset()
        })
    }
    
    deleteCreature(){
        const creatureId = this.parentElement.dataset.id
        fetch(`${creaturesURL}/${creatureId}`,{
            method:"DELETE"
        })
        this.parentElement.remove()
    }

    addLikes(e){
        e.preventDefault()
        let more = parseInt(e.target.previousElementSibling.innerText) + 1
        const creatureId = this.parentElement.dataset.id
        console.log(e.target.previousElementSibling)
        fetch(`${creaturesURL}/${creatureId}`, {
            method: "PATCH",
            headers: {
                "Content-Type": "application/json",
                "Accept": "application/json"
            },
            body: JSON.stringify({
                "likes": more
            })
            })
          .then(res => res.json())
          .then((like_obj => {
            e.target.previousElementSibling.innerText = `${more} likes`;
          }))
      }
}



I used iterators and JQuery to process data and append to the DOM. Once this was completed I had my final product.



Conclusion

This was a challenging but rewarding lesson.I am grateful to have had the chance to further develop my knowledge of rails as well get the opportunity to learn JavaScript.

This JavaScript portion was a challenge. I had no previous experience with this language, but I am grateful to have learned this skill and look forward to further developing my knowledge of it!