I… failed my Code Challenge, but that’s okay.

Here’s my Mod 3 Project Walkthrough. I won’t get into too much detail of the project, but hope this helps with those who are struggling to start. Or if you are trying to build your first full stack website!

Megan Lo
11 min readOct 26, 2020
My Mod 3 Project!

Flatiron School Logistics:

In Flatiron School (my current coding bootcamp), there are a total of 5 mods, and each mod consists of three weeks. 1st week: lecture + lab weeks; 2nd week: more lectures & lab+ code challenge; 3rd week: Project Week.

I failed my Mod 3 code challenge almost 2 weeks ago. I knew I was going to fail, because of something that I couldn’t grasp in lectures. I was then given a choice: retake code challenge or do a solo project. I chose solo project in a split second because I wanted to give myself a chance to actually learn and make my first ever website with both front-end (HTML, CSS, Javascript) and back-end (Ruby on Rails).

In this blog, I would split between walkthrough, what I have learned while making my project, and what I was going through during the week. As one of the greatest leaders has said,

Success consists of going from failure to failure without loss of enthusiasm.

-Winston Churchill

Here’s the timeline of my project:

Day 1: Project Pitch

Day 2: Building relationships between models , some HTML to get a layout of my website, building GET Request, i.e. R(ead) in CRUD

Day 3: Building POST Request, i.e. C(reate) in CRUD

Day 4: Finishing up POST Request, building PATCH and DELETE request, i.e. U(pdate) and D(elete) in CRUD, last but not least using CSS for styling

Day 5: Project Presentation

Writer’s note *spoiler alert*: despite having four models in my project, I only focused on one model and one CRUD for the time being; Git repo of this project is attached at the end of the article.

Day 1

Day 1 was pretty chill. I had this idea using the characters from my favorite comic strips, Peanut, to build a Fall🍂 Edition Event Planner. However, things got a bit complicated when I started building my models. I decided to leave the worries to the next day.

First and foremost, let’s build a frontend and a backend folder with HTML and CSS, and new Rails app respectively.

Frontend:

mkdir peanuts-events-frontend
cd peanuts-events-frontend // direct to the folder you just created
touch index.html // create file inside the folder
touch styles.css

Backend:

mkdir peanuts-events-backend
cd peanuts-events-backend
rails new peanuts-events-backend --api // for the purpose of API-only Rails

Optional step — only if you are pushing both front-end and back-end folder to Github (and I did this anyway). Since when creating a new Rails app, a .git folder is also generated, you could remove this folder by doing this:

rm -rf .git

So yeah, basically that’s what I did on the first day.

(After-Project thought: shouldn’t leave something i could’ve done easily the next day, especially under the time crunch. should have figured all out and started getting some backend stuff, including the models, controllers, tables, etc, going).

(back to the top)

Day 2

I sought out for my instructor’s help for the first half of the day, because I struggled to build the relationship of my 3 models that I have proposed, before I could generate models, controllers, etc, basically the very root of the project.

Here’s my initial proposal:

My 3 models (character, activity, events)

Then, I realized it didn’t work out, since my proposal was:

  • A Character has many Events and has many Activities
  • An Event belongs to an Activity and an Activity has many Events
  • So Event as a join table did not work out.

Therefore, here’s what my instructor suggested:

Now, we have the character_activity model as join model. An Event has many activities and activities belongs to an event. A Character has many Activities through character_activity , and an Activity has many Characters through character_activity .

(Reference: How I built my relationship graphs)

After

rails g character name nickname personality hobby catchphrase image
rails g activity name description event:belongs_to
rails g character_activity character:belongs_to activity:belongs_to
rails g event name description venue location date time

which, not gonna lie, was the best part of the project, gave me this:

All these crazy stuff

Note1: Uncomment gem 'rack-cors' in the Gemfile. That allows cross-origin resource sharing (CORS, duh). Then, bundle install . Last but not least, uncomment the following code in config/initializers/cors.rb and change origins “example.com" to origins “*":

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

Note2: I added the serializers with the Ruby gem 'fast_jsonapi' onto my Gemfile and bundle install so that I could access the serializers. The purpose of serializers is to help organize your complex data, so it’s easier to see and access the necessary data that you need. An example from my project:

class CharacterSerializer
include FastJsonapi::ObjectSerializer
attributes :image, :name, :nickname, :personality, :hobbies, :catchphrase, :activities
end

By giving these attributes, when I access http://localhost:3000/characters , these are the attributes that will be available to me. But this could get tricky later on, especially if you are not familiar with serializers, I ran into a lot of bugs because of that.

Next, I spent the rest of the day (and night) building the first and the easiest step (aside from generating the backend): the GET request (in JS) and the R in CRUD, as well as HTML on the side so to see the layout of my website, so I know what I can insert and create in my Javascript.

Tips: As suggested on our project guide, I did everything layers by layers, in other words, I started working on the character , then activity , lastly, event . I found it so much easier, not only I only had to focus on one thing, but also, it’s easier for me to organize my code (I am crazy when it comes to organizing code, since we have couple hundreds of code to write, it’s always good to know where your code is).

Before I did the front-end stuff, I made sure I put the index route in my Character controller.

peanuts-events-backend/controllers/characters_controller.rbdef index  characters = Character.all  render json: CharacterSerializer.new(characters) # this is when you have the serializer, otherwise, you can simply write "render json: characters"end

Then I went to my Javascript to add my GET request

CHARACTERS_URL = "http://localhost:3000/characters"
function getCharacters() {
fetch(CHARACTERS_URL)
.then(res => res.json())
.then(characters => {
characters.data.forEach(character => buildCharacter(character))
})
}

Essentially, what it means here is

  1. the front-end is going to fetch the data from the provided path in the argument
  2. Extract that response to JSON format
  3. Send it back to the frontend with that information to print it in a way that we could understand.

More details in this Using Fetch MDN. Oh, also make sure you have your rails s running from the backend folder in your terminal.

If you wanted to understand more what happened with my code, I will attach the link of my Git repository at the end of this article!

What I also did while writing my buildCharacter function in JS, I wrote down what I want my HTML output to look like (I don’t recommend hardcoding HTML syntax on the index.html, because I want my code to be dynamic and usable with my other functions. The rule of thumb when coding!)

Alright, Day 2 done. Move to Day 3!

After-project thought: I wish I could’ve done this part earlier, so I can spend more time on the hardest of all — POST request. I underestimated myself and I ended up finishing this part within 2 hours or so, which was considerably quick. The next day was really a torture not gonna lie :(

(back to the top)

Day 3

Day 3 was the worst of the whole week. I spent first half the day getting my buttons done for the layout of my HTML (because I wanted to have a side menu). On the second half of the day, I started working on my POST request. What is POST? POST will be used when you want to upload something new, in my case, creating a new character.

First thing I made sure is to have the create route in my Character controller. Then I made a POST request to make sure it would hit my create route by putting a byebug in my controller.

Controller (backend):

peanuts-event-backend/app/controllers/characters_controller.rbdef create
character = Character.create(character_params)
render json: CharacterSerializer.new(character)
end

POST request (frontend):

peanuts-event-frontend/src/index.jsfunction postCharacter(character) {
fetch(CHARACTERS_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(character)
})
.then(res => res.json())
.then(character => {
//debugger
divDisplay.innerHTML = ''
buildCharacter(character.data)
})
.catch(error => console.log('Errors:', error))
}

POST request explanation:

  1. Fetch data from the provided URL
  2. Send request to backend that we are creating new characters
  3. whatever it is in my character parameter will be what the backend is grabbing and send it to frontend
  4. extract that response to json format
  5. send the data to my function buildCharacter
  6. console.log the error if there is error

Guess what? IT DIDN’T WORK! I tried different things, like putting a debugger in my JS code, moving around my HTML layout, etc. I spent 3–4 hours working on that. It didn’t work and I couldn’t figure out why, so I started to breaking out because of all the stress and headache I had all day. Since I only had one more day and 24 hours to work on more code, the emotions and stress had really gotten me.

Note: If you developers encounter something really similar, consider that as normal. Because this is you breaking your comfort zone and you learning new things. Do I enjoy crying? No. But having positive thoughts in my head really calmed me down.

It was already 1am at that time. Therefore, I decided to sleep on it, tried to work on it the next morning. If not, I would seek out for help. And I was lowkey freaking out because I had one day left, but I had done only one-third of my project.

(back to the top)

Day 4

Credit: Home Alone!!!!

AAAH OH MAI GAWD I ONLY HAD ONE DAY LEFT!

I had so much to do! i haven’t finished my POST request, i haven’t started my PATCH and DELETE request, i haven’t even started doing my css yet which i wasn’t too familiar with 😭😩

But it’s okay, I might have nightmares the night before, but I knew I could seek out for my instructor’s help. And I did for my POST request. Turns out it was some stupid minor mistake I wasn’t aware of.

My instructor gave me one of the biggest and most useful feedbacks that I was aware of and I was trying so hard to work on: look at the root while debugging. There are two types of debugging: forward debugging and backward debugging:

Forward debugging means start from where you started sending the POST request (in my case) and go from there;

Backward debugging (reverse debugging): follow the problems shown and work backwards by putting debuggers to see if certain things are working or not.

I could tell you I am not a very patient programmer and always try to get things done by hitting the wall until the wall breaks. My frustration from the night before really taught me to be more patient and ACTUALLY read the errors (rookie mistake tsk tsk tsk).

Since I had already set up my POST request, I continue to set up my PATCH request.

What’s a PATCH request? You would use it when you want to update something. In my case, edit my character. Or in Instagram term, posting a new comment to a picture is a form of updating of a picture.

Controller (backend):

def update
character = Character.find_by(id: params[:id])
# byebug
character.update(character_params)
render json: CharacterSerializer.new(character)
end
privatedef character_params
params.require(:character).permit(:image, :name, :nickname, :personality, :hobbies, :catchphrase)
end

PATCH Request (frontend):

function handleUpdateFormSubmit(e, value) {
e.preventDefault()
let character = {
image: e.target.image.value,
name: e.target.name.value,
nickname: e.target.nickname.value,
personality: e.target.personality.value,
hobbies: e.target.hobbies.value,
catchphrase: e.target.catchphrase.value
}
// debugger
fetch(`${BASE_URL}/characters/${value}`, {
method: 'PATCH',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(character)
})
.then(res => res.json())
.then(character => {
// just a bunch innerHTML code I added here. Please refer to my repo for details
})
}

There were two things ideally that was not supposed to happen:

  1. putting my PATCH function with my Event Handler function
  2. hardcoding the innerHTML

However, those were the only ways that made sense to me at that time, especially under the time crunch. It worked the way I wanted to but this definitely need to be refactored. (Took me the whole afternoon working on it and with some helps)

DELETE request was very easy. I did it in 15 min.

Controller (backend):

def destroy
character = Character.find_by(id: params[:id])
character.destroy
render json: {"message": "Characted is removed."}
end

DELETE request (frontend):

function deleteCharacter(character, divCharacter) {
console.log(character)
//debugger
fetch(`${CHARACTERS_URL}/${character.id}`, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json'
}
})
.then(res => res.json())
.then(() => {
divCharacter.remove()
})
}

Once I was done with my DELETE request, I was done with the MVP (minimum viable product). I did some CSS by doing a lot of Googling. And here we are!

(back to the top)

Conclusion

I have learned so many things while doing this solo project and the biggest takeaway is how to be better at debugging. I intentionally did not remove byebug and debugger in my codes in this article, because I wanted to show that knowing how to debug would help tremendously while working on the code.

After spending the whole week working on this project with a team of one, there were a few things that I didn’t understand in lectures and code challenge week make a lot of sense to me now.

Even though you may not have read the whole article since it is >10 min read (LOL), we all encounter frustration while programming, yet we learned and grew from the process. I feel more confident than 2 weeks ago to learn new materials and continue to grow. :)

My Git repo: https://github.com/mehmehmehlol/mod3-peanuts-event-planner

Note on Oct 26 2020: I will polish and modify my code when I have more time. I would love to add more functionalities and work on the CSS more.)

Yay to the Peanuts family for inspiring me!

Lastly, I’d like to thank Ix (our instructor) and Adam (our cohort coach) for always being there and help us, as well as my solo project mates (Arpita, Kendall, Will, Scot, and Jonelle) to offer help when I was stuck! :)

(back to the top)

--

--

Megan Lo

Software Engineer @ Citi | I write about JavaScript.