Part of my work with Fetchnotes over the past half-of-a-year involved some brief excursions into coding in the land of AngularJS. Those were not the most pleasant of excursions: for the most part they were frustrating and unsettling. As a proponent of the old school traditions of pragmatic minimalism, Angular felt like a confusing forest of maximalist design and over-the-top reinventing of the wheel. I had deep concerns about the performance and maintainability issues caused by Angular’s special (not in a good way) dependency injection and data binding systems.
Anyone who has had even a brief experience with type systems (or the internals of dependency resolvers) will probably groan when they hear about dependency injection. The resolution of a dependency—for example saying module A depends on module B—is trivial in the base case but grows rapidly in computational complexity when multiple interdependencies are introduced. For this reason Angular offloads all that responsibility to the package manager (commonly bower) and just uses a naive resolution system.
Dependency hell, again
Bidirectional binding for a few primitive values (let’s say, strings) aren’t that bad. Just a few observers to keep track of everything and do the heavy lifting, no problem. However, as you build more complex structured values then you get into interdependency hell again. Changing a subvalue of a bigger value that’s also associated to other values causes a cascading flood of updates across the value binding graph.
Use a needle instead of bazooka