DEV Community

Nathaniel
Nathaniel

Posted on

JS RoR Project

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]
Enter fullscreen mode Exit fullscreen mode

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`;
      }))
  }
Enter fullscreen mode Exit fullscreen mode

}

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!

Top comments (0)