Likely one of the factors contributing to the widespread Javascript fatigue of 2016 are the lofty and hyperbolic claims of the popular projects in the ecosystem. AngularJS has branded itself the “Superheroic Framwork,” but it is nothing of the sort. Well unless the maintainers mean rebooting the universe like they are prone to do in superhero comics.
It is entirely possible that is what they meant since Angular 2.0 is completely different from Angular 1.x. Thankfully for all the developers that made early investments in Angular the 1.x series is not only still maintained, but starting with 1.5 an actually decent framework.
If you are sticking with 1.x like we are, there are a many features which can give you the benefits of the more modern frameworks without the fuss and risk of a rewrite.
Rethink the application around state management
Our application became much easier to maintain once we started thinking about the data-flow as much as the user interaction. Angular in the early interations was better at user interaction than state management, with most state getting dumped without thought on the $scope
. This made data sharing and conceptualizing the data flow within the application unnecessarily complicated.
The method we’ve come to prefer is using services to retrieve and store data that is used within multiple views of the application including nested views. Manipulating one master copy of the object also frees us from having to think about the more complex data-binding and scope inheritance rules. As long as the object of record is being manipulated within a digest cycle all views will update accordingly. We also avoid the confusion that results when a cloned value is manipulated.
While the backend team has been thinking this way about programming forever, this has not been a requirement in a front-end Javascript
The benefits of focusing on state and data is what made React with Redux so popular. While the backend team has been thinking this way about programming forever, this has not been a requirement in a front-end Javascript world dominated by enhancing interactions on short lived pages. With today’s large single page applications, the mindset changes.
Composite the application with Components
It is very easy to dismiss Angular components as syntatic sugar for Directives. Components are a subset of what Directives can do, but are also a better way of thinking about the application. Which is likely why so many of the modern javascript frameworks are oriented around components.
Reasoning about your app in terms of Components come with a few benefits.
- Binding via attributes makes it much easier to visualize what data is being used where.
- Components encapsulate functionality allowing for easier and cleaner reuse.
- Cleaner and easier to read code. Instead of pages of nested HTML, the front end code is a small collection of semantic elements.
Use a real datastore on the front-end
Our application includes a lot of data that is frequently accessed in slightly different ways on different views. Our approach had been two fold. For very common data we wrote a lot of underscore
filters to read through preloaded lists. For more advanced filtering we just went back to the server to fetch the right data with SQL queries.
We decided to incorporate TaffyDB to help solve both pain points. There’s a few ways we use Taffy now.
For very common data we wrote a lot of
underscore
filters to read through preloaded lists.
For the data that is required for every application session we inject the data into page using gon
then read it into TaffyDb.
For data we query from the server we use an interceptor to load the data after every request. Generally this is used to update the state after a create
or update
request to the server.
Using Inheritance
controllerAs
is not brand-new to Angular. However I personally did not find much utility in the feature until Components. This syntax makes the Angular controller
act more like a javascript object with the properties attached to this
instead of passed in through the $scope
.
Back to the situation where we have a view that does almost, but not exactly, the same thing as another view. What we can do now is extract the common bits into a super class that are extended by the specific view controllers. While this has always been possible, now all the code looks like correct Javascript.
Conclusions
These four patterns have vastly improved both the maintainability and the user experience of our application, to the point where we’ve gone from moderately annoyed with Angular to moderately happy.
Angular 1.x is far from dead and between when I started writing this post to its eventual publication Angular 1.6 has been released with more improvements. While it may not make sense to start a brand new project with Angular 1.x, there’s no reason to go through the pain of a rewrite. The best parts of the newer frameworks are already there.