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!
Top comments (0)