CRuD in Three Hours

Gabriel Kutik
6 min readNov 14, 2019

The consequence of failing my code challenge meant that I had to create a Single Page Application that did not refresh. The takeaway was to join what I had learned the previous week (javascript as front end, using fetch), and what I learned in the previous mod (rails as backend), and have them communicating through the lingua franca of JSON.

Unfortunately, I had taken a 30 day medical leave of absence, so my rails understanding was over a month old, and not as fresh as it needed to be. It’s do or die, so I’m keeping it simple. Two models: an Album has many photos. As luck would have it, during a lecture my professor built an entire backend with rails and used a serializer, as if he was giving a step by step refresher. Rewatching his lecture at 2x speed, following along, and pausing when needed, not only was entire back end up a running in a half hour, all the muscle memory of rails that had been weakened was now stronger than ever. And half of the project done: Gains. He also said in that lecture that it was a good time to practice routes. I made sure I had written them out all, rather than relying on resources.

It’s time to get that front end up, pronto. Time spent on CSS is less time spent on CRUD. More HTML elements mean more code to get lost in. All that’s needed is a div on top (topDiv), a div with a button (buttDiv), an unordered list in the middle, and a div on the bottom (photoDiv). Just make sure each has an id, so you querySelect them. Everything else I’m drip-dropping is pure javascript.

First I query selected the three divs, and the unordered list. I also declared globally two variables of album_id and photo_id. I could always set those values anywhere and grab them from anywhere. Used correctly, all information I ever needed was never out of scope.

grab yo elements. set two global variables.

To ensure the slate is clean each time, at the very top, the unordered list and both divs innerHTML gets set to an empty string. The next step is to have a form that can take user input and send the info to the backend. I usually loathe using the innerHTML function for any other than wiping away information, but in this case I will use it for ease setting the names of both inputs. This was so I can grab the information easily with dot notation. My trick here is not to write all of the inner HTML to the topDiv. Instead I create a form, and set its inner HTML, and append the form to the topDiv. This way I can add an event listener to the form. It’s not pretty, but it works.

lines 17 and 19 for that easy dot notation

I had been in the habit of a chaining everything down from an initial fetch, but after a mock challenge review, a coach showed me the value and power of helper functions. Write the fetch in a function definition called pageLoad (just make sure to return the fetch). Then invoke pageLoad directly below it. Due to hoisting, and first class functions, nothing breaks.

Having the makeAlbumList a separate function means I can pass something into later. This was more helpful for the photos, as pageLoad refreshed the DOM for me.

The fetch eventually returned a JSON array of multiple objects. (actually a promise, due to the asynchronous….eerr…nevermind. That’s story’s for another day) And due to the serializer, each object had a key whose value was a nested array. Hello forEach loop. Similarly, this coach taught me that if it has a forEach loop, don’t leave the logic trapped and imprisoned inside the scope of that code block. Have the forEach call another function (called makeAlbumList) and define it below. That way these helper method’s work can always be used later…read: less work for you.

The pageLoad and forEach loop of makeList get my seeds on the page with a button (with an id set to the album_id) and an event listener, and confirms my backend is working.

lines 49 to 69 were commented out.

Before I learned to divide my code in concrete steps, that fetch I had called at the start was frozen. It was called once, and once only. My list was set, and that list was not live. So I would have to create and append elements to the DOM in order to have the change persist. That also created two sources of truth. That’s extra. No bueno. After a post fetch, invoking pageLoad did all the work.

lines 77 and 78 are using the form’s name dot notation. lines 86 and 87 have that sweet sweet es6 sugar. line 91 pageLoad does the DOM. less work for me

Showing an album was just recycling the logic from above. Wipe the slate clean with innerHTML set to an empty string. Set the globally scoped album_id to the e.target.id (the button from line 47). Now this information is never out of scope. Recycle that sloppy innerHTML form from above to save time (now the names are “name” and “url” for the photos)

lines 112 and 114 again having names for that easy dot notation

Next we slap on a few buttons. Want to go to the main menu? pageLoad. Want to delete this album? A delete fetch with globally scoped album_id, and pageLoad. I don’t have to touch the DOM at all. Easy Peasy Lemon Squeezy.

line 126 and 134 show the power of having a function return a fetch, you can call that function anytime to update the DOM

Except for where the photo gets displayed (photoDiv), all logic and elements for the photos are just recycled from what I did above with the album. addPhoto button with event listener is just a rework of addAlbum. makePhotoList is rehash of makeAlbum list. Rinse, lather, repeat. I’m done. The only real change is that pageLoad can’t be used here to refresh the DOM, so what my photo post fetch returns is passed as an argument into the makePhotoList. I never have to touch the DOM. My functions do it for me.

189 and 190 use dot notation. 199, 200, and 201 again with that es6 sugar. 207 updates the DOM for me. Why make life hard?

Doing this project took everything I had learned in the three Mods and put it all together. I finally saw how it all flowed together. The front end sent information through a fetch in the address, method, body. This was captured by the controller as params. The controller checked and validated it through the model. If everything checks out, it gets sent to the server and persists. With photos now persisting, I could make anything from a meme generator to a maze with these images on the walls.

--

--