So here I am, 12 weeks into one of the craziest plunges of my life and it is time to finally jump from the nest, spread my wings, and see what the past four Phases of Flatiron School have taught me, if it was all worth it, and I decided that the best way to find out was to create the App that got me interested in software engineering. If anyone has read my previous blog posts, you may have seen there was a time when I realized I wanted to build things: namely the app that I can say (although in its infancy) has truly come to life. Looking back, I am proud to say that yes, throughout my experience here at Flatiron, I have learned enough to have the basics of my app come to life, but more importantly I have been able to (for the most part) learn how to learn what I need to make my visions real.
So this all started with a dream of setting out my first web app, from scratch from the ground up, in a way that would be accessible to the outside world. I wanted to this in a way that would mimic my own startup as closely as possible. Thus I decided that the best idea was to deploy from the beginning, and test only through deployed frontend and backend. Without any experience this was a huge mistake, as I encountered issue after issue after issue of things that I have never encountered before. It was very much a trial by fire, and unfortunately sucked quite a large chunk of time (that should have been utilized building out features on the app).
So, one of the things I ran into was this what felt like incessant issue running into CORS errors. Although I haven't been able to fix all the bugs that allow seamless communication between my independently hosted frontend and backend environments, one of the main things that allowed the most basic of communication was the Rack-CORS gem for ruby on rails. All I had to do was add
gem 'rack-cors' to my backend gemfile and run
bundle install from my terminal. Then, I was free to create my
cors.rb file in
config/initializers/cors.rb and add
Rails.application.config.middleware.insert_before 0, Rack::Cors do allow do origins 'http://localhost:3000', 'http://localhost:3001' resource '*', headers: :any, expose: ['access-token', 'expiry', 'token-type', 'uid', 'client'], methods: [:get, :post, :put, :patch, :delete, :options, :head], credentials: true exposedHeaders: ["Set-Cookie"] end end
And things started to work ! I stopped getting the CORS errors.
Unfortunately, it revealed a larger problem, that I still have yet to find a solution to regarding the saving of session cookies on the browser and then sending them to the backend server, which I am extremely willing to get help with. (please add in the comments if you are knowledgable with that) but ultimately my CORS errors were no longer a problem.
Sticking with the backend theme, I would like to highlight something I learned and enjoyed using between my frontend and my backend for some interesting fetches. I realized that multiple params can be passed by dynamically creating the path that a fetch would be sent to, in ways that many different values can be passed to the backend without adding anything to the body. for example:
As you can see, this fetch has two pieces of data string interpolated into the address, that in this case send the information about the logged in user as well as who in the database they are forming a relationship with.
This is handled in the backend by the route:
post '/reflect/:user/:mirror', to: 'reflections#create'
and then processed by the create method in the controller:
reflection = Reflection.create!(user_id: reflection_params[:user], mirror_id: reflection_params[:mirror])
In this case, neither of those id's needed to be sent as part of the POST request body, but are available to the backend controller through params just the same. Any number of simple pieces of data can be passed using a custom route like that. Perhaps it isn't a necessity, but nonetheless I definitely found it cool that this could be done.
When calling up a new entry into my database up, and needing to process it, every time I did a .where to find entries associated with a particular user, all I could get back was ActiveRecord::Relation that I couldn't really work with for my purposes, as my unit of data is a hash composed of keys and integer values. To make things more complicated, my .where could return an ActiveRecord::Relation that may be composed of potentially thousands of entries that all need to be processed to yield a neat one-dimensional array that can be served to the frontend for rendering.
I was at a loss until.... I read about the #pluck method !
#pluck is a ruby on rails method that takes as many arguments as you want, these are the keys that correspond to the desired values to be plucked in the same order the keys (symbols) are passed as arguments to the #pluck method, and returns an array of either the values that correspond to the keys, or a two-dimensional array that contains the desired values nested in an array of arrays, each inner array corresponding to the values plucked from one particular entry in the database, leaving behind all the extra information that is impertinent to the calculations or whatever processing that needs to be done.
More can be read on pluck here.
The last thing I want to talk about, which I think is the simplest, coolest, and single-handedly most useful, straight-forward, (and dare I say slick) method I have found for my uses was the #transpose method.
So: having used #pluck to generate a two-dimensional array that contains an x amount of arrays structured in such a way that all the first integers correspond to each other, all the second integers correspond to each other, and so on... and ultimately each column has to be compiled into an average. Instead of figuring out how to pull the first member out of each array, average all of them, and then push them into a new array, I fortuitously stumbled upon the #transpose method, that takes an array and magically converts it from
[[ 1, 2, 3, 4, 5 ], [ 3, 4, 5, 6, 7 ], [ 5, 6, 7, 8, 9 ]]
[[ 1, 3, 5 ], [ 2, 4, 6 ], [ 3, 5, 7 ], [ 4, 6, 8 ], [ 5, 7, 9 ]]
which now automatically "combined like terms" and allowed me to quickly map over the outer array and return an array that contains only the averages of the inner arrays, which is what I wanted all along.
[ 3, 4, 5, 6, 7 ]
This may be small, but I can't even imagine how much work it saved me, all with one simple built-in method.
Overall, however small, these are all different little lessons that I never would have learned if I had not embarked on my own independent project. I feel happy, accomplished, and just that much more ready to take on challenges in the future, knowing that I can ask the right questions and utilize resources (such as this one) and feel part of the software development community, where people are extremely helpful and knowledgable, and have all of the collective knowledge at my finger tips.
Fellow coder, you are never alone.