Building with Elm at SEP Makes

March 8, 2018

Preface

For the last few months, I’d been working on my side project Contact, a JSON REST API written with Elixir and Phoenix, designed to be the backend to an instant messaging platform.

I thought that SEP’s semi-annual hackathon: SEP: Makes, would be the perfect time to make a front end application for Contact, but other than integration testing, I wasn’t entirely convinced that my API was ready for consumption. So in the two weeks prior to the weekend, I prototyped an application in React.

Over the course of the weekend we overcame a few challenges and learned a couple lessons, regarding the tech as well as preparation for the weekend, which I’ll share with you here.

The Pitch

My project pitch wasn’t just going to be making a frontend Javascript application, we were going to build an application in Elm! What’s Elm??

Elm is a functional language that compiles to JavaScript.

It competes with projects like React as a tool for creating websites and web apps. Elm has a very strong emphasis on simplicity, ease-of-use, and quality tooling.

Here is a sample of Elm code to give you an idea.

Why Elm? Elm is known for having very few (close to zero) runtime exceptions and amazing performance.

Considering it took two weeks to prototype most of a frontend in React and the fact that I had never written a single line of Elm, I decided it would be best to merely add an Elm component to my existing React application, which was only a few features shy of completion.

So I pitched that we would build the main feature of the app, the chat window, in Elm with the goal of learning: Functional Programming, Web Sockets, and the process of incrementally adding Elm to an existing application, which simulates what would happen in a real business that would introducing Elm to their product.

Challenges


Dropbox doesn’t handle large file downloads elegantly

I had the ingenious idea to create a Linux virtual machine image for use by my teammates, removing the tedious steps of setting up your development environment (I have heard a few horror stories), but I did not think to zip the files before hand. We spent a good chunk of time figuring out ways to get the 20GB image from my Macbook to my teammate’s Windows machine.

In the end we uploaded the image to SEP’s network file storage system, and then had him download it.

After the weekend, I ended up zipping the file, which was able to shrink it down to 3.5GB (a small enough size for Dropbox), at least I’ll know this for next time.

Using react-elm-components

Needing to integrate our Elm component into the React code, we opted to use the react-elm-components library (written by the creator of Elm).

We scratched our heads over a The function React.createClass is not defined error for 30 minutes before we realized that the library had not been updated since React v16 (we were using v16.2) was released, which removed the function React.createClass.

We monkey-patched the file in node_modules to use the react-create-class library (Facebook published this package to make the deprecation easier to handle) and voilà!, we had our Elm component on the screen.

After our monkey-patch proved it would work, I forked the project on Github, made the change, and then installed my fork instead of the package published on NPM. In hindsight, the library was a very shallow wrapper and easy to understand, which is probably why the project is not being maintained. There are actually a couple of pull requests open that fix our exact problem, but they haven’t been acknowledged by the maintainer.

Decoding JSON in Elm is hard

Contact REST endpoints all return responses that conform to the JSON API specification, which is rather verbose.

When retrieving the full list of messages on page load, we were able to decode the message’s body and sender ID, but we were unable to figure out how to deconstruct the full response to get the sender’s name that matched up with the sender ID.

In the end, I settled to alter the endpoint to return a simple list that held the data we needed, which we would able to decode easily. If I was going to maintain this application in the future, I would most likely revert this change.


Wrapping Up

I believe that choosing to hack on an in-progress project was the right decision, allowing the team to get right to the fun part of the project and getting to skip a lot of the boilerplate that comes with greenfield projects: Creating users, logging in users, etc.

Due to the narrow scope (adding the one component, written in Elm), we were able to complete our objectives! It feels pretty good to come out of a hackathon with your project 100% done and a working demo. I’m already excited to participate in the next edition of SEP: Makes!

Screenshot of Contact w/ Elm