Over the last year and a half, I've been doing a lot of work on a single-page app (SPA) built with AngularJS (a.k.a. Angular 1). I didn't write the initial version, but I was part of a team developing new features for it.
Caveat: I don't consider myself an AngularJS expert.
That said, I plan to steer clear of AngularJS on my next project.
Why not AngularJS?
There aren't a lot of options for doing end-to-end testing with AngularJS. The official recommendation is Protractor, which is built on Selenium. Protractor has its own learning curve, particularly in the way it hides asynchronous calls with "magic." The documentation recommends against using it with PhantomJS, so it's relatively slow.
We disabled all of our Protractor tests. Several team members (I was one) spent multiple days over the course of weeks trying to get the tests to run reliably on our build server. We gave up in frustration.
We switched to unit tests (Jasmine + Karma). These work reliably with PhantomJS. They aren't easy to write, though. Every component requires a different type of test. Want to test a controller? Look up how to do it. A directive? That's different. A filter? Different still. A service? Different. A directive with a template? Different - install and configure a library to handle the template cache.
http://angulartestingquickstart.com/ is helpful for untangling the complexity.
Recently Nightwatch.js appeared on the scene; I have heard it is possible to test AngularJS with this powerful tool.
AngularJS is a framework, not a library. It attempts to provide solutions to nearly every aspect of building a web application. One cost of this approach is complexity. Tutorials may give developers the feeling that AngularJS is simple; it's not. Even after using it daily for months, I learned important facts on a daily basis.
Some aspects are needlessly complex. For example, nearly every time I use ngOptions I have to look up the syntax. One would think that creating a drop-down list from an array of objects and binding it to an identifier would be a common use case.
I distrust frameworks in general; they tend to be less flexible than building an application using focused libraries. If a God Class violates the Single Responsibility Principle, doesn't a framework suffer from the same issues?
I referenced the AngularJS documentation frequently during development. Then I'd go out on Stack Overflow or Google and try to find a clear explanation. The official documentation appears to have been written as a technical reference, and I personally find it difficult to follow.
I lost count of the number of times I forgot that myName becomes my-name in AngularJS. Except with filters.
Moving markup that worked perfectly into a template on a directive caused display issues that we never did resolve.
Here's one that took some time to track down: Angular $http calling success on 404
Angular 2 is here. Much of what I've learned with Angular 1 will be obsolete eventually. How much study time do I want to spend on this? How long will it be around?
If you want to use AngularJS...
Follow the AngularJS style guide by John Papa. The guide is endorsed by the Angular team. If we had started with this, development would have been much less painful.
Avoid $rootScope whenever possible. Think of it like using global variables. Leverage services instead.
Use UI-Router. Don't even start with the AngularJS router. It will paint you into a corner of workarounds and hacks. This article opened my eyes.
What should I use instead?
I don't know. I like React's philosophy, but I'm still a beginner with that. I haven't tried other SPA frameworks (including Angular 2). Consider if you really need a SPA; would ASP.NET MVC plus a bit of Knockout do the job?
Whatever you choose, look for simplicity, testability, and clear documentation. Don't be sucked in by "look how fast you can build a to-do list!" samples.