RadPad made the switch to Facebook-created React.js framework and Flux architecture for our experience of “Finding a Pad”. At RadPad, we are always trying to improve the process of finding a home to rent and React/Flux aligned with our main technical goals. It was a 3 month journey to transition our Angular framework and add additional features in the process. In this article I hope to enlighten those exploring the differences between the two frameworks and convince you why in some cases, Angular (1.X) doesn’t cut the mustard.
RadPad’s original web product was well suited for what’s colloquially known as a thick Front End framework. The reasoning is simple in principle; if the browser loads an entire application on a first page load, then there is no need to ever refresh the page. Instead, elements will get dynamically inserted based on API responses or alternatively when we change routes and swap templates. In this situation we don’t have huge concerns about the weight (or thickness) of the application. Sure, there is some pain for our users on the initial page load, but that quickly dissipates into joy when the smooth transitions to new content feels seamless. This single page application architecture, or SPA, has been a recent pillar of modern web development and is something AngularJS does exceptionally well.
Limitations in the Wild
The difficulty in scaling Angular is another issue that plagued the old RadPad. Angular CAN be scaled with a lot of resources. You can see examples of highly trafficked sites like vevo.com or msnbc.com scaling it beautifully and effectively. These sites show how powerful Angular can be, but if Spiderman has taught us anything its that great power comes with great responsibility. The power is that Angular permits the developer many ways to accomplish goals. This comes with the extra responsibility of clearly defining the purview of Angular components. Angular has documentation that hints at how you should modularize components. The official documentation examples allow a developer to gradually, through osmosis, understand how components are intended to be used. When you hear developers speak about organizing code you might hear language like “that doesn’t feel angular-y” or “that doesn’t seem like the Angular way to do things.” This intuition is something that is picked up over time, but is not something made explicit by the Angular framework. The hazy overlap of what different components should do causes the burden of component architecture to be placed on the developer. Startups don’t have the bandwidth to constantly weigh these decisions. What happened over time for RadPad is the components’ logic were used in a variety of ways. Angular watchers were scattered in different components, controllers and directives weren’t clearly separated, and the scope of which directive controls which functionality became blurred. It caused the code to become difficult to reason about and challenging to modify. While the permissiveness of Angular is great for making things quickly, it eventually becomes a flaw as your application grows and evolves.
New Framework Decisions
Revitalizing the user interface of the Find a Pad experience was a great opportunity to also address new user behaviors and refine our technical goals. We wanted to be friendlier to opening tabs to view listings, improve page speed performance, and increase development speed. To give the reader some perspective, in the past we opened single pads dynamically in modals. It caused the information to feel cramped and inaccessible, but most importantly, didn’t really allow users to compare different pads. This behavior turns out to be essential for empowering people to make a renting decision. Opening a single pad in a new tab window would allow our customers the ability to compare the benefits of different pads and allows RadPad the extra real estate to tell the narrative of moving to a new home. Our main goals suggested React with Flux was the best way to approach building the site. It could give us the ability to lighten each perceived page load time while also mitigating the complexity of our application architecture. It had the added benefit of allowing future optimizations by rendering React server side to improve SEO and page speed. We don’t want to make it seem like this was an easy decision to make. It meant a majority of the code base would have to be rewritten and that many programming perks Angular give you for free could not be directly translated. The team had a sum total of 3 weeks of past React experience largely dedicated to watching Pete Hunt (@floydophone) YouTube videos about React.
The Pains, The Joys
We believe React is clearly the better framework for RadPad’s “Find A Pad” goals, but the development process of translating an Angular site to React wasn’t as clear cut. Digging into old code meant we were effectively relearning how components did things on a case by case basis. Since Angular is somewhat of an MVC-ish structure we couldn’t directly translate the components to Flux which has a unidirectional flow of data. If we wanted to abide by Flux’s clear architectural pattern, we had to use Angular merely as a blueprint and extract pieces of code when appropriate. It wasn’t fun because a majority of time we were refactoring legacy Angular code while simultaneously processing how it fits into a new Flux paradigm. Often times we would completely rebuild a feature because this process was too convoluted to reason about.
During this translation we had a renewed appreciation for how Angular structures asynchronous API calls. Anything REST heavy Angular is a pro at tackling. Using ngResource or http service is wonderfully simple. Deferred promises created in a factory are then immediately passed back to the original component that requested them. This is pleasant because you handle the different responses within the domain of the call. It also allows for tidy modularization because the component can easily identify the current state of the API request and response of the promise. We wrestled with a comparable way to do this with the Flux architecture. After a lot of research we determined that there was no agreed upon best practice for how to handle this. Anything resembling Angular’s promised-based system led to smelly code. We ended up using what we termed a “resource component,” a modified immutable store, that would handle any API actions. It’s callback would be a “setter” action creator that changes an application state. It feels somewhat impure to do it this way, but still follows a unidirectional data flow. This topic still needs some more exploration.
There was also some initial pains in the verbosity of Flux. For example, it was taking twenty lines of code for a click on a button to send an action through the application, change the application state, and reflect the state change in the UI. It’s a long-winded process that would make some jQuery enthusiasts smug about the fact it could take them only one line of code. Over time, however, the irritation of more code relents to the beauty of interface composability. You structure the needs of the components only once. The components rely on pieces of information called properties to be passed to them. All they care about is the properties they receive and then handle how to interpret this data within the interface. Setting up one action creator change and one component with expected properties lays the groundwork for future reduced code. The next time you want to change the user interface you can piggy back on the previous action pipeline, having the state change already reflected within the component. This arrangement turns out to be an incredibly easy way for developers to build a mental model of what is happening in the application. Although Flux is more forcefully restrictive in how data is moved throughout the application, this becomes a godsend as things get complex because you intuitively follow the data flow. What you are trading for with React/Flux is convenience for conceptual understanding that can be shared across multiple developers.
Angular and React are tools that excel at different things. The decision to choose one over the other shouldn’t be based on what’s in vogue, but should be analyzed based on what aligns with the technical goals you have. One of the great things about RadPad’s startup culture is we are able to pursue different technologies and ideas for the ultimate goal of improving our customer’s experience. If you want to feel this excitement for yourself, checkout some pads at www.onradpad.com
. Also, we are always on the lookout for people that share our passion. If this article has piqued your curiosity in any way and sounds like something you would want to involve yourself in— check out our jobs board a www.onradpad.com/jobs