Prototyping with AngularJS
A typical AngularJS project starts with prototype development on the very same platform. The idea is to paint a vision for front-end user interaction with useful static information for the intended audience.
The challenge we often face is balancing the trade-offs between meeting short-term goals for prototype development and hitting long-term milestones for shipping a final product. What might seem to be the best choice for short-term goal can create a large debt in the future, and trying to do everything right the first time can end up being wasted effort that risks the deadline. So how can we best use our resources and meet the demand and deadline for prototype development?
Use libraries, and pick them right the first time
There are good AngularJS libraries available to you for implementing useful features right away, though not too many.
When looking for AngularJS libraries, be sure to check all of the alternatives before committing to one. Typically, implementations of libraries vary and cannot be swapped out easily. Just because the purposes they serve are the same doesn’t mean they are integrated into your app the same way.
“Prototype to Learn – Prototyping is a learning experience. Its value lies not in the code you produce, but in the lessons you learn.” – Andrew Hunt and David Thomas, The Pragmatic Programmer
Be sure to conduct usability testing as often as possible because sometimes the only reason you need to replace the library is because users don’t like how it works. For example, I had to change a library for slider UI two times so it would behave exactly the way the testers expected it to.
Avoid hand-picking high coupling dependencies
“Don’t Program by Coincidence – Rely only on reliable things. Beware of accidental complexity, and don’t confuse a happy coincidence with a purposeful plan.” – Andrew Hunt and David Thomas, The Pragmatic Programmer
There are lot of front-end technologies available in the open-source community: LESS vs. Sass, Bootstrap vs. Foundation, AngularStrap vs. AngularUI, etc. It gets complicated when they are carefully and individually ‘hand-picked’ in an effort to build the ideal development setup from the start.
It was also common to see both AngularStrap and AngularUI being installed on the same app. They also depended on specific version of Bootstrap to work properly, and sometimes minor version differences made changed the output. In general, using a feature from AngularStrap and another from AngularUI wasn’t the best idea, since both were trying to serve the same purpose and required different setups in the app to do something similar.
The verdict here is to look for a cohesive set of Front-End stacks that are sure to work together really well. For example, we utilize ngBoilerplate, which has opinionated structure and ensures that specific versions of dependencies such as AngularJS, Bootstrap, and AngularStrap will be in harmony. You can also utilize Bower, which warns you of incompatibilities at a glance.
“Before software can be reusable it first has to be usable.” – Ralph Johnson
It is easy to over-engineer the AngularJS app, especially since it offers a great MV* framework with helpful utilities such as services and directives. For example, a simple widget that lists the latest 5 news can be turned into its own HTML view, controller, service, CSS, etc. By the time you are finished developing just one page in the app that consists of 10 little widgets, you could end up with 50+ new files to manage.
“There Are No Final Decisions – No decision is cast in stone. Instead, consider each as being written in the sand at the beach, and plan for change.” – Andrew Hunt and David Thomas, The Pragmatic Programmer
Although it is recommended to group files based on features for scaling your app, it can be counterproductive to do so in the context of rapid prototyping. Even when project scopes are limited to simply building an app based on wireframes and mockups, it is almost inevitable that you will need to introduce changes, from minor to major, as stakeholders realize what they really wanted, or as priorities and goals shift.
“Don’t Be a Slave to Formal Methods – Don’t blindly adopt any technique without putting it into the context of your development practices and capabilities.” – Andrew Hunt and David Thomas, The Pragmatic Programmer
Modular components are critical for future scaling of apps. However, it can be more productive in the short term to get the page up and running with as little work as possible to show progress for stakeholder review. Once you go through few iterations, you can make a far better judgement regarding a code block and how it should be turned into a modular component.
Don’t try to mix Controller logics and Models in Views
You don’t need to worry about making everything modular, but you do want to make sure things are easily modifiable. It is tempting to define temporary variables on the fly and add ng-if and ng-class conditionals in the views to replace the purpose of your Controller.
At first, it may seem like a productive approach for the prototype process. But it only makes iteration on features (or how simply how it’s displayed to users) more difficult . If you wrote something flexible once in the Controller, you just need to modify a few lines of code and let the Views automatically react to it.
“Write Code That Writes Code – Code generators increase your productivity and help avoid duplication.” – Andrew Hunt and David Thomas, The Pragmatic Programmer
This is where spending more time thinking and coding the right way the first time yields greater benefit than writing code that is limited to working in exactly one way. You can still have all the functions stored in as few of Controllers as possible to avoid over-engineering.
Have a single source for storing data and magic numbers
Duplicating data and magic numbers is just as destructive as duplicating lines of code. When you define your own dummy data during prototype development, you may be tempted to create an object containing lots of data within a controller. This is not a horrible approach for quickly trying something out, but it is certainly not ideal when the app eventually has to get it’s data from an external source.
It requires more steps, but you want to start this off right by creating a JSON file with a dummy object and defining a Service that gets the content and passes it back to the Controller asynchronously. With this approach, the app will have an end-to-end flow from start to finish, which is more important than focusing on finishing individual pieces without having a clear picture of what’s ahead. When you move into production, all you have to do is modify where the app gets its data, and the other features should work the same as before.
Magic numbers are commonly present in prototype apps because things are loosely defined in the beginning. What are the thresholds for negative, neutral, and positive? How many table rows to show at a time? They are often the source of confusion and a point of hassle when arbitrary change requests are made to alter the numbers, whether or not they are used throughout the app. To avoid such issues, you can define magic numbers used throughout the app using a service or $rootScope so that there is absolutely one single source of data. It can also be used to store brand color HEX values for use within libraries such as Highcharts.
Coding for AngularJS Prototype apps requires you to consider both short-term and long-term goals. There are parts of development you can improve progressively over time and other parts that need to be done right the first time. You want to be adaptive and strategic in the scope of prototype development so that you can maximize the utilization of resources you have at hand.