Monthly Archives: June 2016

What I learned from a React code challenge

I’m currently on hold with the Oregon Employment Department, and as a result don’t feel that I have the focus to design and implement some extra features. I’ll write a blog post instead!

An employer emailed me and asked me to complete a code challenge: create a simple to-do list in React. You can see the todo list I built here. I would have liked to style it a bit just to show off my design and CSS chops, but I focused on implementing features and ran out of time.

I’ve written todo lists in React before, but I always followed a tutorial. In this case, I kept honest and wrote everything from scratch. Without someone guiding me, it took longer than I expected, but I learned an awful lot more! I found myself really enjoying this challenge.

I probably made some beginner mistakes, and implemented some anti-patterns. If you notice any in my code, I’d love to know about them.

So.

Step one was to find a React and Webpack boilerplate. I was googling around, and found plenty of super-complex, production-ready solutions. They transpiled ES6 or 7, and included hot module reloading, local dev servers, deployment scripts, and test helpers. I didn’t want any of those. I wanted something that would use Webpack to build all my JSX modules into one JS file that I could include in some basic index file I could open in my browser. So I Googled “react webpack barebones boilerplate”.

This very simple template is one of the first things to come up, which is surprising because it simply doesn’t work. Among other things, you need to include and use the React-dom module to render things to the DOM these days.

So I forked it, fixed it, and PR’d it. We’ll see if the maintainer accepts it, but now I could move forward with the challenge!

And like 70% of my time has been looking up and remembering syntax. I’ve written a fair amount of React and JSX, but I’ve written far more Ember and Angular. Generally, the “data down, actions up” philosophy makes plenty of sense. I think you can get a good sense of my workflow and thought process by looking at my commit history.

One of my first steps was realizing that React’s getInitialState() function unintuitively (to me) sets a component’s initial state.

Another important realization was that a component’s render() function is called every time the DOM is updated. For a while, I assumed it was called only once in a component’s life, but the fact that it is frequently called means that work done and defined within it is essentially dynamic.

And finally, I had to re-learn how to send actions up through the component hierarchy. I’m not using a Flux implementation here, so there’s no dispatcher involved. If an action at a low-level needs to change something higher-up, it needs to somehow invoke a function its parent passed down to it through props.

Instead of calling a prop function directly from the render, I found that delegating to a locally-defined dispatcher function (I’m not sure what the proper terminology is here) solved a lot of problems. That is to say, instead of this:

render: function() {<button onClick={this.props.addThingie}></button>}

do this:

render: function() {<button onClick={this.handleClick}></button>},
handleClick: function(e) {this.props.addThingie()}

Not only is this prettier, but it gives you more flexibility. Instead of the addThingie() function only getting access to the click event (and thus its target and its value), you can pass addThingie() anything you’d like. Possibly something from the child’s state, or something that is computed within handleClick(). You can also do more work within handleClick(), such event.preventDefault().

In my code sample, I haven’t gotten the time to implement todo editing yet, but I am now confident that I could do so! Before this code challenge, I wouldn’t have had that confidence. That’s pretty cool.

Leave a comment

Filed under Uncategorized

The Jacket.

This is just a little anecdote about a hackathon I went to in 2015. There isn’t some big declaration at the end, but if there is a thesis or moral, it’s this:

Fun is tremendously important to me.

And maybe:

Do scary things.

I signed up for a hardware hackathon (Hack to the Future, held by hackster.io and the super-great Adam Benzion) with my friend Stephen a while ago, just after graduating from Dev Bootcamp. It was a super uncomfortable position for us: not only were super green as developers, being barely able to cobble together a crappy CRUD app, but we were (and are) web developers. We knew next to nothing about hardware. It was terrifying.

I distinctly remember the first morning of the two-day hackathon. We were supposed to mill about and socialize. Stephen and I were so intimidated that we almost left without participating. We managed to dare each other into sticking it out for at least a little while. We had paid for entry, after all.

I talked to a few people, and was continuously made aware of the fact that I was inexperienced, out of my element, and that all my hardware ideas were stupid. I floated the idea of building a telescoping hat that could telescope up and down, partially joking. People let me know it was a stupid and out-of-place idea. I agreed and kept quiet, fuming.

Eventually, it came time for people to announce project ideas out loud; if someone was interested in your idea, they would come over to you and teams would form sort of organically. As it came time for me to yell out, I quickly edited my original thought:

“IT IS 2015, THE YEAR IN BACK TO THE FUTURE 2, AND WE STILL DON’T HAVE THOSE JACKETS WITH RETRACTABLE SLEEVES. THAT’S WHAT I WANT.”

I got laughs and applause, and then I got a team: Stephen; a computer science student (Martha) and an engineering student (Stephanie) from SFSU; and a couple pals (Ken and Tinic) with deep hardware prototyping experience (e.g. laser cutting and 3D modelling and printing). After that, I actually had to turn a couple people away. People were excited to build this stupid project of mine. I was gushing, proud, and terrified. Then we got to work.

Marty McSleeves was born.

Vincent wearing the jacket while Stephanie works on wiring it together

A lot of the time, I served as team mannequin.

It was magic. One of the team members donated a jacket. Martha and I did some sewing. We modelled and printed the spools and housing, spooled fishing line on them, sewed them into the jacket’s shoulders. I spent all night at Noisebridge in the Mission sewing washers into one of the sleeves! The servo motors (housed in components built by Ken and Tinic) were controlled by a Spark core, which exposes its internal methods as an easy-to-access web API. Those methods were written by Stephanie and Martha. Stephen wrote a web client using Node and Express, we deployed it on Azure, and Bob’s your uncle. More than once the spools got tangled and jammed, and some API calls were behaving erratically, but we had done it:

A jacket whose sleeves would go up and down based on a button you click in your browser, and I got to call myself “team lead” the whole time! And we made it in 48 hours! I am still stupidly proud of it.

You can see the Hackster project page here.

the 3D printed components in the jacket, and the servo motors they housed.

Servos with 3D-printed spools and their 3D-printed housing, which would later be sewn into the shoulders of the jacket.

Here’s a video of this janky, hacked-together thing in action.

I made friends, I had fun, and I learned a lot by doing something I was totally uncomfortable with. I think this was true for my teammates as well. It was a huge personal win.

Then came the judging.

Which, I dunno. I have very mixed feelings about judging in hackathons. Unless there’s a specific need for it, I tend to favor the approach of “the team that had the most fun won!”. But we had judges, and they had criteria.

We set up our table like it was a science fair, and I delivered our spiel. As it happens, when the judges saw our results, the jacket’s spools were jammed and we couldn’t demo. I hardly saw that as an issue. We showed them a video instead.

But the judges were obviously disappointed. They followed up by asking me what sort of market I foresaw for this kind of product.

I said this was for fun. Obviously no one would or should try to market this.

We got an honorable mention.

Almost every other team got a special sponsor prize with an actual reward. Almost every team also tried to create something useful or marketable. I somewhat bitterly suspect our mention was a consolation prize.

There is nothing wrong with creating a product that helps people or is profitable. Indeed, those are good things that we should usually strive for.

But this was a hackathon. I approached as a space in which to create without judgement, cut off from the demands of Silicon Valley. I was bummed! Oh well. By my criteria, we won by miles.

There are other hackathons out there with a philosophy closer to mine, e.g. the beautiful Stupid Shit No One Needs and Terrible Ideas “Hackathon”.

The Snackathon

And in a couple weeks, I’ll be self-hosting what I’m calling the Snackathon, a tiny little hackathon among friends with a similar idea. Maybe every single project will win an esoteric and customized prize. Maybe they will be snacks.

The primary goal is for it to be fun. Let me know if you’re interested!

I’m so stoked.

Leave a comment

Filed under Uncategorized

A reintroduction to TDD

So I’ve been writing a forest.

And I’ve been writing tests for it.

It’s been a lot of fun, and I’ve gotten a second wind on the project in the past couple weeks. I’ve written a bunch of code!

However, a lot of features have yet to be implemented. The code I’ve been writing has largely been RSpec, which you can see in this PR. As of right now, most of those tests fail, which isn’t a mistake.

I’ve been TDDing the forest a lot. Not everything, but a lot of things. Professionally, I’ve always regarded TDD like veganism: yes, you can make a lot of great arguments in its favor that I cannot honestly counter, but I just can’t imagine myself actually following through with it. So while I’ve historically written tests, they usually don’t come first.

Good arguments against TDD exist, and I certainly don’t think it’s the be-all and end-all. Some people are really off-puttingly dogmatic about it. But I’ve discovered, personally and for the first time, reasons to do it.

  1. It’s meditative. I’m not going to substantiate this because it’s very subjective, but there. It feels good.
  2. Non-passing tests act as a very difficult-to-ignore to-do list. I have a bunch of to-do lists devoted to the forest, including Trello, post-it notes, and #TODO and #FIXME comments scattered throughout my code (which is great for indelibly affixing a task to a particular line), but nothing encourages me to act more than a yellow or red dot in a sea of green.
  3. I’m not on a timeline. TDD does take longer up front, at least in my experience. Maybe one day I’ll get good enough at it that that won’t take any longer than writing the other way around. Of course, professional projects usually are on a timeline, so this reason might not convince your boss.
  4. It makes my coding intentional. Every time I write a method, it is to get a particular behavior. If I start building a workaround that goes off into some space not covered by the spec, I feel it immediately.
  5. It makes my code prettier. This is also subjective, but I think it does.

I’ve definitely complained about TDD before, because if you are in a time crunch it can feel very, very slow. “What do you mean I have to write code before I can write my code? This is bull!”. But this forest is a nice place. There’s time to do things right here.

Leave a comment

Filed under code, Uncategorized

Layouts with JBuilder and rails-api

Rails-api has been merged into normal rails, but this is what I’m working with. I’m fairly certain the process will be identical for someone using the new setup!

I wanted to build an API whose responses had a reusable wrapper, just like an HTML response can be wrapped in a reusable header and footer. The process to do this is easy, but not totally neat, for reasons I’ll get into.

Anyways, here’s what you need.

# app/controllers/application_controller.rb
class ApplicationController < ActionController::API
  include ActionController::ImplicitRender
  include ActionView::Layouts
end
# app/views/application.json.jbuilder
json.head("This will appear in every response")
json.body(JSON.parse(yield))

JSON.parse(yield) stands in for the normal yield you are used to when rendering HTML with erb or what have you.

This code is not ideal because the use of JSON.parse(yield) means that the body of your JSON response is parsed twice. It is hella inefficient.

I’ve done a fair amount of research, and it seems this is simply a limitation of JBuilder. This Github conversation confirms this. If anyone hears of a good solution or workaround, please let me know! And I think ActiveModel::Serializer is not the way for me, but I would love to be convinced!

I suppose you don’t even need to include ActionController::ImplicitRender but it has made my life a whole lot easier! It means you don’t have to specify which jbuilder file to load at the end of a controller; Rails will try to figure out which one based on naming conventions as it does with normal erb views. If your goal is to try and get rails-api to behave like Rails but with JSON instead of HTML, then you need ImplicitRender.

Leave a comment

Filed under Uncategorized

The forest is better!

Thanks to an unexpected PR from a friend, the forest is in good health. The polymorphism issues I was having in the last blog post are all but solved, and all tests are passing. There need to be *more* tests, for sure, but things are looking much better now.

The Location#objects helper hack method still exists, but that’s okay because all the other ActiveRecord helpers I’m used to are back. Wolf#location and Location#wolves both work out of the box. Trogidu, the writer of the PR, saw to that. He also found a couple pluralization issues! I suspected those would turn up, but I was missing the extra pair of eyes!

I’m not working on this project as frequently as I ought to, but every time I put an hour into it I’m astounded by the amount I learn. Trogidu’s PR introduced me to inverse_of, which I somehow had never heard of before. Plus, it made me feel all warm inside that someone I haven’t spoken to in a while took enough interest to help me write code!

Also, the dev blog seems to be following a pattern of humanistic status update post followed by a more specific post on a particular technical thing. I think it’s a good pattern. I’ll follow this one by a quick post on JBuilder layouts.

Leave a comment

Filed under code, Uncategorized

Reverse polymorphism, aka polymorphic join.

I’ve built and implemented a bunch of stuff I’m excited about with the forest, but this post will focus on one aspect: reverse polymorphism. I don’t have it working perfectly yet (EVEN THOUGH IT SHOULD BE WORKING WHAT THE HECK) but I think it is the solution to the craziness I had been encountering with the ActiveRecord associations I need. The best part about it is that it’s not Single Table Inheritance (STI), another potential “solution”.

I’ll describe the problem that needed solving, and how this solves it, and why it’s awesome. Then I’ll describe what’s not quite working yet, the workarounds I’m using, and plea for help from those more knowledgeable.

First, though, here is the gist which introduced me to RP in Rails. I’ll explain how it works in a bit.

The forest’s fundamental blocks are Location objects. They’re normal AR objects. Locations have_many objects, and objects can be multiple kinds of things. The toy examples in the app right now are Wolves and Trees. Wolves can move around, and Trees can’t, but both have_one location.

Ideally, I’d like to be able to call Location#objects and receive a list (an ActiveRecord::Relation) that looks like [wolf1, wolf2, tree1]. I’d like this to work at the ORM level (i.e. I want ActiveRecord to do it for me) and not have to write that scope or method myself.

Polymorphism to the rescue

This sounds like a job for polymorphism, but it’s not a classic case. The normal case is an object being able to belong_to one of multiple kinds of things. I need an object to be able to have_many of many types of things.

It took me a day to grok this, but the solution is a join table. In my case, a LocationObject.

  • Location has_many LocationObjects
  • LocationObjects (the join table) have a polymorphic have_one association with Wolves, Trees, etc.
  • Wolves and Trees have_one LocationObject as object
  • Location has_many Wolves and Trees through LocationObjects.

So the associations are all set up. Location#location_object AND Wolf#location_object work.

Someone might say “well Vincent, this is totally more complicated than Single Table Inheritance!” and I would say “ugh come on”. Classical inheritance sounds like a great solution until you see what it does to your database. Even though Wolves and Dogs intuitively could both inherit from a hypothetical Canid class, which inherits from a Mammal class, and so on, this means that everything that inherits from the base class shares the same table. Every time a single child needs a new attribute, it gets added as a column to the ancestor table.

Because the forest will hopefully have a widely-branching tree of life, this is not the proper solution for this project. That single table would probably get huge, and track information for everything from number of leaves to most recent meal. Or whatever. It would be painful.

To keep shared behavior manageable, I’m going to be relying on composing with modules. To continue the previous example, I’d have a Mammal module, and a Canid module, both of which would get mixed in to the lowest-level Wolf and Dog classes. I’m keeping these modules in lib/.

Hell yeah. This seems like the perfect solution.

The Problem

The problem I’m having is the join. Location#objects and Wolf#location do not work. I’ve created the following fix, which I really don’t want to be permanent:

# app/models/location.rb
... 
# FIXME
def objects
   self.location_objects.includes(:object).map do |location_object|
     location_object.object
   end
 end
...

While it DOES avoid a potential N+1 issue, I’m pretty sure ActiveRecord is capable of doing this for me. And as long as this is a pet project, I want the code to be beautiful. I’ve even got failing tests demonstrating this behavior.

Another symptom of this is being unable to create the objects as I’d like. Wolf.create(name: "joe", location: some_location) just doesn’t work!

The plea

WHYYYYY?

It may be the ActiveRecord just doesn’t handle those helper methods over polymorphic join tables. But the writing I’ve seen online doesn’t suggest that.

I have a terrible fear that this is a naming or pluralization issue. ActiveRecord’s errors hint at that: Could not find the association :location_objects in model Wolf.

Anyways, here’s the relevant code. I invite feedback!

location.rb
location_object.rb
wolf.rb

1 Comment

Filed under code, Uncategorized

It’s just an API for now.

Alright, episode two in the development blog of my little forest project.

Here’s the forest code.

If you look at my Github contribution tracker, you’ll notice a month gap there. There’s a couple reasons for that, but the relevant one is that I was trying to work on the front end. I was learning how to get React + Redux running with Webpack and Babel and all that fun stuff. I was learning about modern JavaScript development and deployment.

I spent a couple weeks following Survive.js’s awesome Webpack and React tutorial. I don’t think I will continue down that road for right now. I’m just doing Ruby for now. I am capable of learning the modern front-end, but it will probably have to be with more time or mentorship. The complex mixture of compilers and languages and package managers is too much for me to handle at the moment.

So that’s that. I’m building an API for now. With Ruby on Rails. Once it’s fleshed out I’ll start looking at a front-end. I’d love for it to imitate the style of text adventures like Zork, except the world is dynamic and alive. Every movement (e.g. north, south) would constitute an API call. Clearly, web technologies are not the best way to build this. I think Z-machine is the way to go for that.

So that’s a status update. I’ll write a follow-up post real soon re: technical issues on the back-end.

Leave a comment

Filed under code, Uncategorized