Down the Reddit hole

More progress today, with the addition of proper user profiles, the ability to save and hide links, a sidebar for navigation, some bug fixing and better CSS. Major features missing include pagination, a proper navigational bar on top, and thumbnail support, but it’s getting there! (And more widespread AJAX/smart rerendering)

The most interesting discovery of today was finding out that you can actually override templates based on which controller is rendering the view. This came in very handy to design the navigational bars, and it would be pretty useful to do a separate mobile website version too. This made me look at inheriting from my controllers as well, though so far I haven’t found a practical example where this would be useful (unlike polymorphic associations, which I use for comments and votes, with a single “polymorphic” controller).

I also reinvented the idea of the has_many_and_belongs_to_many association when I noticed a lot of nearly identical code between my save and hide features, but I remembered that it’s usually not a good idea to use because it makes it much harder to evolve from a “mere” join table in the future, so they’re not really worth the small amount of time (or code) they save.

Skeleton in the closet

Not a lot of progress today due to being sick, other than improving the user interface and getting subscriptions and favorites fully working, and finishing up the nested comments. There are still a few missing features like saving/sharing, and feeding the website with actual data from Reddit.

Working on this project has been challenging not so much in terms of doing things, but in learning what are the best ways to do things for maintainability and performance. I have a lot of templates already and organizing them isn’t obvious, and I need to pay close attention to my SQL queries to make sure they aren’t inefficient.

The ghost in the shell

Got started on my Reddit clone project! The basic functionality is here, with users, subgroups, links and nested comments, and ways to navigate around the website and create new content. There’s still a lot of core features missing, most notably profiles and votes, and the design is only very basic CSS for now.

I intend to write a more responsive frontend with Backbone as time permits, which seems like it might pose some challenge to do well. I’m currently using the standard ERB templates from Rails, which wouldn’t translate well on the client side. Maybe duplicating the code on the client side will be less of a problem than I expect, though it still seems pretty annoying compared to using a template system that can be reused on both ends.

Done.js

Today was a brief tour through Node.js, which ended with writing a chat program that use Websockets (specifically the socket.io library for compatibility). The end result was pretty cool with shared messages, nicknames, multiple rooms and private rooms, with the ability to extend the server to include more commands as necessary.

Node.js felt very natural to use for this sort of application by just passing callbacks around and using a similar design on both the server side and the client side, though it seems it’d be a fair bit more awkward for more traditional websites closer to the design of Rails. And debugging was pretty interesting as usual with Javascript…

Geist of Code Future

More Backbone today, working on an clone of Gist on Github. While Backbone does help with abstract some of the lower-level details of writing single-page applications on the client, it still feels like there’s a fair amount of busywork going on at times. It’s a marked improvement over just using jQuery (or only the DOM itself! shudder), though, and it’s helpful to see the broader picture of where all the pieces fit together.

Throw the dogs a backbone

So we started out on Backbone.js, and like the title hints at, I must admit this has been the most challenging part of the course so far! Having to deal with the DOM and keeping callbacks/events in mind and figuring out the best way to organize your program so you can keep an abstract overview of things has been pretty tough (plus Javascript’s… quirky error detection, occasionally resulting in no line number in error messages).

Our application for the day was simply posting blogs and creating/destroying/editing them through AJAX only, so the whole application feels responsive, and playing around with events and editing (the last feature allows to edit any field on the fly by just double-clicking). Pretty neat, though doing it on the client-side feels a lot more tedious compared to Rails handling most things for us on the backend.

The funniest bug of the day: Backbone model#save not actually running the success callback if it only got a 200 (OK) status code, it needed an actual output as well, even though the documentation seemed to imply the status code itself was enough.

Day 5: Cleansing the Source

Almost no Javascript today, joy! Instead we went back to Rails a little to make a simple application using AJAX, with a detour through Underscore templates. The concept is pretty simple but the implementation looks pretty tricky, and I shudder at the thought of doing this in pure Javascript… but jQuery provides a functional abstraction to make things Just Work, making using AJAX a fair bit simpler. Our source files were still pretty messy at the end of the day, still!

This is it for this week, with only Backbone (and node.js) remaining as major items on our calendar, nicely dovetailing into our progression towards less rudimentary client-side views. And the 10-year-long process of actually gaining experience in how all the pieces of the puzzle fit together… or learning to avoid all the traps that Javascript springs on you (latest one: asking for a non-existent property of an object is apparently valid and will merely return undefined instead of an error).

(Ajax is actually a popular detergent brand in parts of Europe, which results in a weird mental image for me…)

AJAX Cleaning Product

Snake eats its tail (eats its tail (eats its tail))

Ouch! Today was probably the most brutal day in the course, with a twin introduction to CSS and jQuery, and it’s fair to say that CSS is a pretty mysterious beast for all of us! The basics of jQuery feel more approachable and certainly more sensible, though by no means trivial either. At least I’m running out of pitfalls to fall into with Javascript… the only one that happened today was forgetting for a few seconds that you need to return or break out of switch statements, which was pretty benign.

We made browser interfaces for Tic Tac Toe, Towers of Hanoi and we wrote a quick Snake game from scratch, all in a day’s work, which was pretty impressive, though our CSS is, well, rather rustic (centering items is proving to be a lot trickier than it sounds). We scraped by with enough knowledge to get our games working, but it’s pretty obvious that we’d need a much more sound grounding in browser work to be able to a more visually pleasing outcome!

(Bonus credit: writing the draft of a Mastermind browser game in the evening. The code is still pretty clumsy but it’s functional!)

To boldly crash where no program has run before

Bugs and typos everywhere was the name of the game today. The game was actually Asteroids, but development felt a lot more error-prone compared to our Ruby adventures. We kept forgetting to pass in arguments, to properly invoke functions or to correctly reference functions in another (namespace) file, and Javascript does very little checking of its own, making such mistakes more annoying to track down (and automatic checker tools are less useful than I had hoped for).

Still, we did get our game working on the HTML canvas at the end (sans fancy explosions), with collisions, inertia movement, wrapping around the field and shooting. We wrote the code in a class-oriented way, using inheritance to derive common functionality from a MovingObject “parent”, but using class orientation in Javascript felt a little awkward and like working against the language, compared to what we were doing in Ruby. I don’t know what a better alternative would be (if any), but it did feel like we were missing out on using prototypal inheritance more directly.

{your body}

Second day of Javascript! Again we went over previous problems we’ve done in Ruby, including Tic Tac Toe and Hanoi (which were very simple affairs), and a few slightly trickier problems involving Javascript callbacks since we were doing I/O (through node.js). Nothing very difficult today still, outside of keeping tracks of which function ends where, and remembering that all the I/O has to be asynchronous.

Javascript feels like a relatively simple language still, minus its quirks and warts, though its focus on functions can make for pretty interesting code from the examples I’ve seen in our Javascript books, e,g defining properties on function themselves and use them for memoization or future lookups. Pretty interesting stuff!

Solving Hanoi reminded me that it’s quite an interesting problem mathematically wise, if a bit boring with a computer… the simple recursive algorithm is easy to implement, though the induction giving the optimal number of moves (2^n -1 moves for n discs) is a bit harder to prove! And apparently it’s feasible to solve it by using binary numbers too (which I guess isn’t very surprising based on the formula).