ReactBoston 2017

The best of the tweets, plus a write-up for the Wayfair Engineering blog.

I spent the weekend at ReactBoston, soaking in more knowledge than I thought my brain could possibly hold about all things ReactJS. Wayfair hosted the conference, which in my completely biased opinion was awesome—as I told a coworker today, I feel lucky to work at a company where I feel encouraged to participate in the local tech community and supported in my desire to learn and grow as an engineer.

I went in on Saturday morning intending to liveblog each talk but was so completely engrossed (and so overwhelmed by the nonstop flow of quality content) that I abandoned that idea pretty quickly. I did write up a quick summary of the conference for the Wayfair Engineering blog, which covers some overall themes and a couple of mind-blowing highlights. To sum up: React Fiber (which was officially released yesterday!), GraphQL, surprises, and overall feelings of goodwill.

I tried to touch upon the biggest things, but I couldn’t squeeze all of my favorite moments, speakers, takeaways, or tweets into the post. Among the things that didn’t make it in, but were a huge (or hilarious, or both) part of the weekend for me:

Kansas Day 2017

“We cross the prairie as of old / The pilgrims crossed the sea, / To make the West, as they the East, / The homestead of the free!”

Photo: “Kansas Morning” by Garet Gabriel

It’s Kansas Day, which normally means that I post William Allen White’s “A Song for Kansas Day” for all of my fellow wandering children of Kansas.

This year, though, “The Kansas Emigrants” by John Greenleaf Whittier feels more appropriate:

We cross the prairie as of old
The pilgrims crossed the sea,
To make the West, as they the East,
The homestead of the free!
We go to rear a wall of men
On Freedom’s southern line,
And plant beside the cotton-tree
The rugged Northern pine!

We’re flowing from our native hills
As our free rivers flow;
The blessing of our Mother-land
Is on us as we go.

We go to plant her common schools
On distant prairie swells,
And give the Sabbaths of the wild
The music of her bells.

Upbearing, like the Ark of old,
The Bible in our van,
We go to test the truth of God
Against the fraud of man.

No pause, nor rest, save where the streams
That feed the Kansas run,
Save where our Pilgrim gonfalon
Shall flout the setting sun!

We’ll tread the prairie as of old
Our fathers sailed the sea,
And make the West, as they the East,
The homestead of the free!

General Assembly WDI, Week 12

Capstone project!

end of an era

Week 12 was strange for many reasons: it was the final week. It was a short week—we had Friday off because of Veteran’s Day. Tuesday was Election Day, which….

It was also our final project week, which meant I spent most of the week sequestered in one of GA’s shiny and tiny new conference rooms with coffee and Ember and Rails. Using Ember for our final projects was optional, but I jumped on the chance because a) client side routing; b) I wanted the practice; and c) it sounded fun.

Regarding that last point:

I chose to use Rails for the backend (instead of Node/Express) because it’s a fairly natural pairing and because we had roughly a week to build the project, and I’m more comfortable with Rails than Express at this point.

It’s been two months exactly since I presented my project—sorry for anyone waiting with bated breath to read about my final week at GA—so in the interest of finally getting a post up, instead of doing a detailed blow-by-blow of that week, I’m going to cover the highlights. If there’s anything that piques your interest, leave a comment or get in touch via Twitter/etc., and I’m happy to expound!

Project Planning

When I first seriously starting learning JavaScript, beyond copying & pasting random code to hide and show things on web pages when I was a kid, I started playing around with the idea of building a tool that would generate a random pattern for a quilt, made out of squares and triangles of different colors. This was inspired by the desire to build something super visual, by Libs Elliott’s stunning and unbelievably cool work to generate much better/more intricate patterns with Processing, and by my own interest in quilting.

My first attempt at building this resulted in 335 lines of JavaScript in a single file, nearly 200 of which were inside of a single onclick event. Also: when I abandoned it in November 2015, it didn’t work, and my commit messages were shoddy enough/my use of branching nonexistent such that I couldn’t remember when it last worked and what I had done to break it.

I decided to take this opportunity to revisit the idea and expand upon it, adding the ability to register, to save/favorite different patterns, and to create “projects” associated with specific patterns that would let users write up notes on actually making the pattern into a quilt and photos of the process/the finished quilt.

Prework: File Uploads with Paperclip and Rails

I started by working on photo uploads: we had briefly covered how use Multer/Express/AWS S3 to upload photos and store URLs to a database, but I needed to apply this knowledge to a Rails API and to Ember. I knew I would need to re-scope my project idea if I couldn’t get uploads to work, so given the tight project timeline, I decided to focus on this first, give it a day or so, and move on if I hit too many roadblocks.

I set up the API and scaffolded a very basic “pattern” resource—at this point, I was thinking that I would need to store the generated pattern as an image (I’ll come back to this later). Following along with a General Assembly repository on using Paperclip that’s a couple of years old/out of date, and is no longer being taught by GA Boston, I installed Paperclip and ImageMagick to help with uploads through Rails, then wrote a curl script to test whether I could POST image data to the API without yet storing it in S3. I had to write a slightly different script than the ones I had been using to send JSON data through POST requests; this Stack Overflow post on data types helped.

I installed the aws-sdk gem, which Paperclip uses to store files on S3, and added the necessary AWS config variables (s3 region, bucket, access key ID, and secret access key) to my .env file so that I could use them in my config files. From there, I used curl to test the upload process and make sure that files were being successfully stored in S3 and the URL saved in my database.

Success! I wrote up my process as an issue on the GA Paperclip repo for a few other students who were hoping to do the same thing in their projects, then moved on to working with Ember.

This was…frustrating. After spinning up a very basic Ember project using the Ember CLI, I tried multiple different plugins/components/guides, including ember-data-paperclip, ember-cli-form-data. In the end, I just wrote a basic HTML form, set the enctype to multipart/form-data, and used JavaScript to get the form data by the form’s ID instead of trying to use any Ember fanciness (though apparently using event.target instead of the ID is a better approach?). I also wrote a short custom upload service to send the AJAX request in the correct format.

This took two afternoons, mostly working solo/Googling like mad, but also checking in with one of the GA instructors, who was also attempting to crack this challenge. (Not at all #humblebrag: proud to say I solved it first!) This was one of my first real moments going “off script” at GA, and it was frustrating and awesome and confusing and wonderful. It’s one thing to take a lesson with step-by-step instructions and well-documented code and apply it to your own very similar project; it’s another thing entirely to take snippets of tutorials and gem/plugin docs and a rough sense of what you want to do and make it work. I know this problem isn’t a gigantic one—many, many people have successfully solved it, and I’m sure there are much better, cleaner ways of approaching it than the one I ultimately took—but it was cool to find my own way through the fog.

Resources in Ember & Rails

Saturday afternoon was spent on Ember: integrating authentication and generating some basic routes/models/components. In the process, I switched from using a simple join table and has_and_belongs_to_many to connect Users and Patterns to building a Favorites resource and connecting Users and Patterns using has_many :through—this was prompted by a question I raised about how to do a post to this join table without having a separate, named resource; a good list of the arguments in favor of has_many :through is in the response here.

While working to get data transfer happening smoothly between Ember and Rails, I ran into some confusion around serialized data for many-to-many relationships. This was solved by tweaking my models in Rails; Ember likes to receive IDs (instead of full JSON records) for associated data (details on how to do this are in this issue).

Quilt Pattern Generation

By Saturday evening, I was ready to start tackling pattern generation. I decided to use the (aptly, if coincidentally, named) Fabric.js library to help with this because it makes exporting data from an HTML5 canvas in different formats super easy. Fabric is so fun to work with!

I also got the chance to write another, more detailed custom service in Ember to handle the pattern generation. There are a number of ways in which I’d like to continue refining this, including streamlining the code that draws each individual quilt block (a square or one of four different triangles), adding a way to calculate the total fabric yardage needed for a quilt based on the final number of blocks of each size and color, and letting users choose their own color schemes. That said, this was an amazing opportunity to revisit old code I’d written and figure out how to make it better. I cut the size of the file roughly in half, with the longest method around 50 lines (STILL VERY LONG, but definitely not 200!).

In the process, I also realized that I don’t need to upload anything to S3 for patterns—no need to store these as images; I can just store them as SVG strings which are smaller, load faster, and are easier to scale for different screens and views. Hooray! (Also: I feel like I’ve come a long way with SVG.)

Ember (Days 54-56)

One of our instructors warned us that working with Ember would be an emotional rollercoaster, and HOO BOY was that true. I cycled back and forth between “I LOVE THIS” and “I HATE THIS” more times than I can count. Two months later, I think this was largely because I was trying to do a bit more than was reasonable within my time frame, I was basing my project off an Ember repo that was given to us that had auth built in (which was nice) but also a pretty intense pre-set template of nested components/styling choices that I had to figure out how to dismantle to get what I wanted out of the project (which is still not 100% mobile responsive, which irks me but not enough that I’ve gotten around to fixing it), and, to be honest, because it was election week. Wednesday was a rough day.

I don’t have a ton to report here, which I realize makes for a less than brilliant blog post, but I will leave a couple of notes/thoughts here:

An issue I wrote on how to write a component that does the same action in multiple different parts of the app without repeating that action’s code in multiple different Ember routes. The advice I got was to inject the Ember store into the component, which allows the action to happen at the component level instead of passing it up to multiple different routes to happen there. This is unconventional at best (and some might say a terrible idea), but was an interesting way of getting rid of a ton of redundant code.

GA provides guidance on how to deploy our projects to the web using Heroku (for our Rails APIs) and GitHub Pages (for our client side code). The deployment instructions were oftentimes a bit shaky—I suspect this is the product of having so many different cohorts and instructors and of rapidly changing technology. I ended up writing a condensed, shorthand version of the Rails & Ember deployment guides for my own use that addressed some of the errors/missing information in the existing guides, and then shared it with enough friends that I ended up posting it as an issue for everyone in the cohort.

Lastly: huge thanks goes to my mom, who took the time to beta test Quiltr and actually made a quilt based on one of the patterns I generated, which is featured on the app’s home page. This made my presentation at least 10x cooler than it would have been otherwise.

Quiltr

Quiltr

Create patterns. Make quilts. Be inspired.

Live app: https://rhjones.github.io/quiltr/
Live API: https://quiltr.herokuapp.com/
Ember repo: https://github.com/rhjones/quiltr
Rails API repo: https://github.com/rhjones/quiltr-api

General Assembly WDI, Week 11

Ember!

Week 11 of Web Development Immersive was all about Ember (the JavaScript framework, not the IOT coffee mug or the surprisingly tasty “toasted chai cider”).

Day 49

Important things to know about Ember:

  • Ember is an open source JS framework. It’s mostly used to build web apps, but it can be used for mobile or desktop apps (e.g., Apple Music).
  • Like Ruby on Rails, Ember is an opinionated framework that follows “convention over configuration.” It provides a lot of built-in structure and help, as long as you follow patterns. In exchange, you get to spend less time setting things up and piecing them together. (The downside: if you want or need to break conventions for some reason, you have a lot more work ahead of you than if you were using a less opinionated framework like Backbone or a library like React.)
  • Ember handles client-side routing (which makes me very happy, as I established in last week’s post). Routes in Ember parse a URL, connect a router to a template, and load any necessary data into that template via a related model. Routes can also redirect (for example, if a guest user tries to access a route that’s only available to authenticated users) and handle actions that involve altering data or transitioning to a new route.
  • Ember writes most AJAX calls for you, if you follow convention. Ember is a fan of JSON API, but you can customize an Adapters to tell Ember how your API is formatted and how to interact with it. Adapters handle the relationship between your data and how you store that data (on the back end, in Ember’s cache, and in test fixtures).
  • Ember caches data on the client side, which makes your apps faster. Ember also allows you to change data on the client side without persisting it to the server (which creates something called “dirty attributes”).
  • Ember binds data, meaning (briefly) that updating a piece of information will update all persistently related information—we’ll talk about this more soon, but the gist is that Ember 2 uses one-way data binding: data is bound down (from a model associated with a route down through templates/components), and actions affecting that data move up (from a component up through to the template to a route and the related model). This is a change from Ember 1, which used two-way data binding, in which changes made in the view are automatically updated at the model level. With large, complex applications, this can slow things down and cause unintended consequences that can be hard to track down and debug.
  • Ember 1 used views and controllers; Ember 2 has shifted toward components. Components have templates (not unlike views) and contain properties and methods associated with specific UI. You can invoke a component from a template associated with a route or from another component. Components don’t have access to the broader scope of a route—their scope is defined explicitly at the location where they’re invoked. Components are modular and reusable—an example might be a button to “like” a video on Vine, which is shown when you’re looking at the specific video and also shown next to each video when you’re looking at a list of videos.
  • The Ember command line interface (CLI) is a handy tool that simplifies the process of setting up Ember apps. The Ember Inspector is a browser extension that helps with debugging and inspecting Ember objects in the browser.
  • Ember uses special Ember Objects (which are a class in Ember), which enable data binding in Ember. Among other things, using Ember Objects allows for the creation of computed properties, which calculate properties of an object based on the values of other properties of that object. Computed properties “watch” the properties on which they depend and will update on the fly as those properties change. They’re a little bit like virtual properties in Mongoose, but they’re more aware.

Cool things to know about Ember:

  • Ember was created by Yehuda Katz, who was also instrumental in Ruby on Rails and jQuery (and created Handlebars). Ember feels a lot like Rails in many ways, and uses Handlebars for its templates.
  • There’s an Ember conference on the Boston Harbor Islands each summer, which sounds awesome.

Day 50

Routing

Tuesday was about routing and components. We talked first about static routing, which you might use for something like /about, which would display a view containing your hypothetical personal library site’s “About” content, or /books, which would list all of the books. We then talked about nested routing—let’s say your /about view has some general “About this library site” content, but you actually run the site with two of your friends, and each of you has a bio and a personal philosophy on literature that you’d like to display beneath the About content at, say, /about/helga. Nesting routes lets you display the content for Helga inside of the About content. Inside the template for the /about route, you add Ember’s {{outlet}} helper. When you visit a nested route (/about/helga), the template for that route will render inside of that helper.

Next up: dynamic and resource routing. Resource routes in Ember (or Rails, or other frameworks) are routes that are associated with a specific data resource—the /books example above is one, as it maps to a books resource on the site’s back end. Conversely, /about is not a resource route, as (in this example) it doesn’t draw on any data; it contains static content about the site. When you’re working with resources, dynamic routing becomes important—we might expect a route that looks something like /books/1 to show us the first book. Dynamic routing lets us create routes like this without having to specify a route for each individual book. Instead, the route contains parameters that indicate which resource to load within a view. Instead of /books/1 and /books/2 and so on, we can create a route for /books/:book_id to handle all possible cases for us. (As a side note, this isn’t a new concept—we covered parameters like this in Rails in Week 5.)

Components

On to components: components are reusable pieces of UI within an Ember app. Knowing when to split component out of a template is a bit of an art, but generally, if you’re starting to work with replicable actions (for example, a button that looks like a pencil that means “click this to edit something,” that you want to reuse for different kinds of objects throughout the app), it’s a good idea to use a component.

A few things to know about components:

  • Components can be nested within routes and within each other, and components can be used multiple times in a single view.
  • Components must have at least one dash (-) in their name to prevent clashes with HTML elements and help Ember recognize them automatically.
  • Components don’t have a model hook, meaning any data they receive needs to come from a parent route.
  • By default, Ember wraps all components in a div. You can customize a component’s element and its class, if you want.
  • Components can “send” actions up to their parents, which is how you would, say, move from clicking the pencil button next to a blog post up to a route that recognizes that what you want to do is edit blog post #7 and transitions you to the correct edit view. This is Ember’s “data down, actions up” convention at work.

Day 51

Now that we have a better handle on how Ember applications are structured and how to map routes to views (which may or may not contain components), it’s time to talk about data. As already mentioned a few times, Ember uses unidirectional data flow: data down, actions up. Data comes in through a model hook that is associated with a route, and is passed down through that route’s template to any components. When actions happen at the component level, they are bubbled up (using sendAction) to the route. Data is only ever changed at the route level (generally speaking / when following best practices), and the UI only changes when something changes in the data store or after a successful response from an API call. This is called “pessimistic” UI, where the UI is the last thing to update. This is different than frameworks that use two-way data binding, where actions at the component/lowest level take immediate effect on the UI and simultaneously persist any changes on the back end.

Data binding in Ember involves, in part, passing the correct data down to a component. Let’s say you have that edit button, and you want to include it in the view for a single book. You might do something like {{edit-button book=book edit='edit'}}. In this example, edit-button is the component; book=book points the book value in the component to the book data coming in from the model, and 'edit' is the name of the action bubbling up from that component (this.sendAction('edit')), which the route is listening for under the name edit. We’re binding the book data down, and sending the actions back up to the route.

Ember applications include Ember Data, a library that handles data models and interaction with those models through adapters and serializers. Adapters handle making requests to servers. Adapters enable Ember to interact with data stored in a variety of places and formats, from localStorage to WordPress to Elasticsearch to Rails. (Ember Data also works with streaming servers, for apps that update in real time.) Serializers format the data on its way to and from the server. Ember comes with three different serializers (JSON API, JSON, and REST), but you can also write custom serializers if your server provides or expects data in a different format. An example: we worked with an API that returned a piece of information called content. “Content” is an internal property used by Ember Data, which means we needed to rename this data to something else so we could use it in our app without causing conflicts. We wrote a custom serializer that renamed “content” to “item,” which solved the problem.

Collectively, Ember Data, adapters, and serializers allow you to work with data via models and the Ember data store. Different routes (or component that send actions up to routes / display data that is bound down from routes) ask the store for data through different models. Data needed in multiple parts of your application is fetched only once and held in the store, and different pieces of UI can then quickly grab the data they need from the store rather than making redundant requests to the API. This speeds up your application (you’re not waiting for the response to an AJAX request every time you switch to a new view), and puts all responsibility for fetching data in a single place (the store), rather than splitting it out across different components and routes.

Day 52

We spent Thursday working with templates in Ember and building out a simple todo list application. As mentioned above, Ember uses Handlebars as its templating language; Ember comes with a handful of built-in Handlebars “helpers” that do things like conditionally display content or loop over content. You can also write your own helpers to do things like format date and time values. Ember also has a set of built-in input helpers for working with forms (you might notice there’s no way to use a select element with these helpers—fellow GA grad Jen Weber has written up a simple guide to creating a select element in Ember.js targeted at beginning Ember users).

Day 53

On Friday, we talked about authentication in Ember. We were provided with an Ember template that includes the code to handle authentication via a Rails API that follows the Rails API template also provided by GA. The gist:

  • The API requires users who want to access protected resources to sign up with an email address, a password, and a password confirmation field that matches the password.
  • The API requires users to sign in (using their email address and password) before accessing protected resources. The API returns a token from a successful sign in request. This token must be included as a header with all requests for protected resources, as well as on requests to sign out. The token is deleted/invalidated on sign out and cannot be used again.
  • The Ember application includes two custom services, auth and ajax, which are injected into one another.
  • The auth service uses the ajax service to make the appropriate AJAX requests for sign up, sign in, change password, and sign out. Upon successful sign in, the response data from the server (user id, email address, and token) is stored in a credentials object. On sign out (whether or not the response from the server indicates success), the credentials object in Ember is reset, and the data is cleared.
  • The ajax service extends ember-ajax, which offers methods to make AJAX requests in Ember. The custom service sets an Authorization header before AJAX requests that includes the authenticated user’s token, if there is an authenticated user. This header is used for all requests Ember makes to the API, which gives authenticated users access to protected resources throughout the app.

After covering auth, we were given Friday afternoon to start work on our capstone projects, the last piece of the Web Development Immersive program (!). Friday afternoon was one of the hardest/best days of all of GA for me—more on that in my Week 12 / capstone project post, which I promise is coming soon(ish).

General Assembly WDI, Week 10

Hungarian folk dancers and Hugo.

Day 45

Monday was “Computer Science Day,” which put me squarely in one of my happy places. One of my favorite things in all of Boston is the Bean machine at the Museum of Science, which illustrates the central limit theorem (specifically, the law of normal distribution, aka a bell curve):

Searching & sorting algorithms (which, along with data structures, were the primary topics of the day) tickle that same space in my brain, and come with even more fun videos. Some of my favorite resources for learning about those algorithms, and by extension Big O notation and time/space complexity:

For the data structures portion of the day, we split into groups and each researched a single structure, then presented to the class. My group had linked lists, which are really fun to draw on the board (but maybe not as much fun as tries). Some good resources for learning about these:

  • The CS50 week 5 notes and the “Data Structures” section of the study guide
  • The Wikipedia articles on the major types we covered (lists (including primitive arrays, stacks, and queues), linked lists, associative arrays, trees, graphs, and tries) are pretty good. Wikipedia also has an extensive list of data structures.

Days 45-47

We kicked off Tuesday morning with a giant brainstorming session. The prompt: what technologies and related issues have we not yet covered? It was a long list, and not nearly exhaustive. The goal was to provide starting points for our next assignment: a 15-minute presentation on a topic of our choosing.

This was fun. And overwhelming. And fun. My brain jumped immediately to things I’ve worked on or heard about at Berkman—digital security, Internet censorship (which one colleague chose for her presentation—I was excited to point her to the OpenNet Initiative and Internet Monitor!), Elasticsearch, Kibana, PGP/GPG. I decided to go a completely different direction for my presentation, though, and chose to talk about setting up a code blog with Hugo.

I’m a little behind (only now writing about Week 10 of 12, even though I finished the program in mid-November), but I’ve been doing my best to blog about the code I’m writing and the concepts I’m learning since starting the Web Development Immersive program. I think it’s one of the best things I’ve done for myself as a developer. I’m not always as clear or concise as I’d like to be, but going back through my notes, attempting to distill concepts, and giving myself a second chance to dig into anything that was confusing or particularly intriguing the first time around has helped me retain information, get feedback from others inside and outside of the program, and test my own understanding.

Why Hugo, specifically? Mostly because I’m getting a bit frustrated by WordPress’s bloat and would like to see if I can make the experience of blogging and browsing a bit faster. Jekyll was my first thought, given the size of the community (huge), its connection to GH Pages (which I’ve used for the last four of my public projects), and its use of Ruby (a language I’d like to get better at), but Hugo won me over for its speed argument alone, given that I’d like to port over this blog, which has over a decade’s worth of content. I haven’t yet gone through the process of exporting all of my content to markdown/comments to Disqus and importing them into a Hugo site, but it’s on my to-do list. In the meantime, I put together a quick presentation/tutorial about how to get started with a very basic portfolio site (above) and managed to spark interest in a couple of classmates, which was exciting.

Day 48

I don’t have enough exclamation points to convey my excitement about CLIENT SIDE ROUTING!!!! One of my frustrations throughout the program has been that all of our single page apps only handle/offer a single URL. Want to share a Go Bag packing list with a friend? Nope. Want to send around your Happening event invitation? Nope. Finally getting my hands on (one of) the (many) tools to solve this problem felt so good.

Some basics, if you’re unfamiliar with client side/front end routing: A lot of people are building “single-page applications” these days, which load data dynamically, behind the scenes, as the user interacts with them. The page is never reloaded in the web browser, which makes the user experience a bit faster/more seamless. Because you’re only working with a single web page, you also only have (by default) a single URL. You can check out my packing list app Go Bag for an example of this—logging in, signing up, creating a packing list, editing items, and viewing different lists all happens at https://rhjones.github.io/go-bag/. This is a bummer: what if you want to share a list with a friend? Or send them directly to the sign up page? Or (wait for it) use the back button in your browser? None of this works “out of the box” with a single page application.

Enter: client-side routing, which solves this problem by mapping different parts of a single page web application (like a single packing list, or the view that lets you create a new list, or the log in form) to different URLs. Suddenly, you can bookmark URLs! Share them! Go back and forth between them using the buttons in your browser! It’s like having your single page application cake and eating it, too.

There are larger front-end frameworks that will handle this for you, but we dipped our toe in the water using Router5. We started with a simple HTML page with three divs and a nav bar with three matching links. Each link was tied to an event handler that, when a user clicked the link, would add/remove a “hidden” class to the appropriate divs to “swap out” the desired content. Along the way, the URL never changed.

Using Router5, we refactored this code to instead define a series of routes that matched the previous links and register a series of URL paths based on the internal anchor links. Clicking on one of these links now uses the navigate method of Router5 to navigate to a specific route (i.e., change the URL and execute code associated with that route). We also defined a middleware function that is executed on each transition between routes. This function takes care of adding/removing the “hidden” classes to display the content associated with each route. Ta-da! Functional, shareable URLs that map to specific pieces of a single page JavaScript application.

The goal here was to demonstrate, very simply, how client side routing works and to familiarize us with the concept of associating specific view states with different routes in preparation for working with Ember, which we covered in Week 11. Ember uses Router.js, not Router5, but the principles hold.