Throughout my career, I have worked on quite a few Angular projects. In this post, I will go through some of the different projects I have worked on and explain the lessons learned in each so you can learn from them.
Ionic + Cordova mobile app with AngularJS (2015)
This app was about creating an app with AngularJS and Ionic which was for a school wanting an app for their students to see relevant information. The app was rendering its content from a custom-built CMS created with ASP.NET.
One problem with Ionic + Cordova app at that time was that the animations, eg. when changing page, were quite laggy on lower-end phones and the feel of the app didn’t seem that native. In later versions of Ionic and Angular 2+ the experience has gotten a lot better.
Lessons learned
In this project, I learned the power of creating a CMS for controlling the content in an app, eg. the information to show on the contact page. This is especially helpful when doing consulting, as it gives the customer the opportunity to change stuff later so that we don’t need to do trivial updates ourselves eg. update the copy. Now obviously, there are limits to how dynamic the app stores are allowing your app to be, as you eg. are not allowed to download js bundled from an external server in an app as the app store is not in control to inspect the app before it changes.
AngularJS app for kids with ADHD (2016)
The deal with the app was to create an app for structuring education for children with ADHD in elementary school. It was developed as a MEAN stack app.
This app was developed according to lean startup best practices with interviewing domain experts (psychologists and school teachers) and getting feedback on each iteration with REAL end users.
This consisted of the application split into servicing three different kinds of users:
- The students that were to follow the education. The use case for them was to sit with the app and be guided through the education eg. a math class, getting math exercises presented to them at the appropriate times scheduled using what is called a “time timer”. After each lesson, the assignments were sent to the database so that the teacher can access it later and use it to track the progress of the child.
- The teachers used the app to plan education for students and track and evaluate the children’s progress.
- The school admins that had all the teacher’s rights + access to create and delete users and change passwords.
Lessons learned from this project
This project did a lot to finetune my AngularJS skills and I learned a lot about software development practices that make the project succeed.
- The power of following the lean startup process. And here I mean REALLY follow it, that means ACTUALLY interviewing domain experts and end-users. And ACTUALLY getting each new feature iteration tested by a REAL end-user (no, your college doesn’t count, unless they are a real end-user). And REALLY ditch a feature, regardless of the sunk cost, if the feedback is not positive. Easier said than done. A lot of companies UX’ers have “The lean startup” book lying on their desk but last time they talked to an end-user was years ago, if ever and are making complaints that it is hard to get in touch with a real end-user, don’t have time, etc.
- User management with OAuth for handling different access rights for the students, teachers, and admins. This was handled by a NodeJS Express server.
- The importance of automated tests (unit, integration and end-to-end) as we were doing continuous delivery to a demo site, that regularly got used by our beta users.
- The limitations of the MEAN stack. At that time in early 2016, the MEAN stack (MongoDB, Express, Angular and NodeJS) was a super hot technology stack. What I liked the least about it was using MongoDB as an “all-purpose” database as it didn’t provide the same transactional guarantees as eg. MSSQL as well as the data structure were to be normalized, which was not the most convenient thing to do with MongoDB (and using Mongoose for ODM).
App for collecting bank loan offers (2016)
This application was a little startup project for offering better mortgage prices and loan prices to customers by creating a “Momondo for real estate loans”. The idea was simply to let the user fill out the necessary information receive a loan offer and broadcast the information to the banks in Denmark so they could respond with a specific loan offer.
Lessons learned from this project
Even though this was created as a React app the principles learned here apply as well.
- A stepper flow starting with a low commitment form converts the best. Users bounce if you present them a big form upfront but is more likely to go through the same amount of questions if you let them “buy-in” slowly by creating a stepper flow with short simple forms and convey to the user that they are almost done. Obviously also, avoid all unnecessary questions in a sign up form as every extra question will harm conversions.
- React (at this time at least) is a way less opinionated framework than Angular and I ended up importing a lot of different NPM projects from Github which I didn’t quite like. So this experience with React actually got me to prefer Angular even more, now obviously I don’t have much experience with React since this project and it probably has gotten better by now. Check Angular and react comparison here.
Creating a welcome flow for a bank (2016)
This project was about creating the onboarding system for a big bank including full-stack development with Angular and ASP.NET.
What I learned from this project
- How to create a stepper flow with forms best practices
- How to “bend the rules” in regulated environments by allowing for continuous delivery by being sneaky with the cards dealt; We had a central FE service that was a big pain to deploy to but instead hooked the CI up to deploy to a Sitecore server exposing the files as static content. We then fetched the JS dynamically once the HTML was loaded from the central regulated FE server minimizing the need to deploy the central FE server.
- Also, one interesting observation: The people that were rising to the top in the company were the ones that could and dared thinking outside of the beaten path to create more efficient ways of working and were not too concerned with playing Mr. Nice guy. What got you here will not get you there.
Creating a dynamic questionnaire app for a bank (2017)
This project was about creating a dynamic questionnaire app for a bank. It was done in a big SAFe setup with multiple feature teams (horizontally sliced sadly).
What I learned from this project
- How GraphQL can be used as a BFF (back end for the front end) and provide a facade for the app. This both improved performance as everything the app initially needed could just be specified in the initial query at app init and be fetched from the different microservices, located on the same network as the GraphQL service. Also, this provided for a nice abstraction to mock out data if some endpoint was not available yet (due to the next point…).
- This project taught me the importance of how to avoid abuse of a microservice “architecture” by keeping the teams with “high coupling” colocated together. One of the biggest challenges with the project was that the front end app needed to render itself dynamically from a back end, being developed by another team located in the other part of the country. The coupling between the frontend and backend was so high that every change to the UI and the contract between FE and BE required a meeting. It also caused frustrations and a fragile setup as when the backend didn’t return exactly what the feature needed, the front end would be broken. All of this could have been fixed if the backend containing the UI rendering data as well as the Angular app was maintained by the same team. This is a basic principle of software development called “high cohesion – low coupling” applied on the architectural level here.
- This also learned me how to render an Angular form based on JSON data. ngx-formly is also a nice tool for this if we could live with the dependency on the third-party framework.
Creating an agro culture web application
This app was about creating an Angular app for the farmer to manage his farming using an administration dashboard. He could perform tasks like seeing his fields on a map and plotting tasks to be done on the farms for later running the tasks automatically on his farming machines.
What I learned from this project:
- How to implement real continuous delivery and go from deploying to production every 6 weeks to do it 5+ times a day with fewer bugs.
- Creating a reactive architecture using Redux and RxJS.
Creating an app for au pair match-making/cultural exchange (2019)
This app was creating a match-making-like experience between au pairs and host families. The au pair signed up and answered some questions about themself to go through the enrollment process. The host families could then check out au pairs and schedule interviews with the ones they liked.
What I learned from this project
- The power of using a monorepo architecture vs. NPM packages as this was a huge enabler for more code sharing and faster development. Read more about how to do this here.
- Modals should always update pessimistically and generally overusing modals in an app can be a pain for that reason.
- Autosave can be a pain to maintain and it might be better to split the app up in smaller forms (stepper) and save on completing each step (by clicking eg. next)
- Luckily, this time, the questionnaire service and apps were maintained by the same team (in contrary to the questionnaire banking project) but there are still sometimes where creating a dynamic rendering configuration for something (that might even be a one-time thing) is overkill compared to just hardcoding the specific question. You can then always later integrate it into the question rendering engine if the question needs to be used in multiple places. Read more about this in the hardcoded, dynamic and hybdrid approach blog post.
Performance tuning e-commerce site (2019)
This project was about an e-commerce site having problems with performance on a site created with Angular.
The team had already tried the “best practices” with performance tuning: service workers and lazy loading but still had problems simply because their main bundle was huge – they were loading a lot more than what they actually needed to display the initial route and were not being economic with the bundle sizes.
What I learned from this project
- The key to fast load time performance is to make the main bundle as small as possible (at least under 2 MB for public sites, see here how bundle sizes affect load time).
- Splitting above and below the fold in separate bundles will make the main bundle smaller and thus improve the load time performance
- Only import one UI library in your app for smaller bundle size
- This later led to my blog post about improving load time performance in an Angular app
- Angular Universal is a trade-off between faster first paint time but slower time to interactive due to more js needed to be parsed (first the server bundles and then the client bundles).
Creating a mobile and online bank with a shared codebase using Ionic and Capacitor (and initially NativeScript) (2019)
This project was about recreating a complete mobile and online bank using a shared codebase. The mobile app was built with Capacitor and a UI library that wrapped Ionic components (like in an adapter pattern).
What I learned from this project
- If you want to create a UI library, make sure that you have a team full-time assigned on it. Otherwise, if they are also involved in feature development, that will eventually take their focus away from creating and maintaining a usable UI library. Also, open-source help with providing transparency and inviting external developers to contribute to the UI library.
- Learned that NativeScript (in our experience) didn’t provide a better user experience than just running the app in a web view with Ionic and Capacitor in terms of feel and smoothness (NativeScript were actually quite slow at rendering simple pages). Also, you run into hard to troubleshoot bugs when you use a cross-platform technology (eg. React Native and NativeScript) and no developers have the full expert knowledge to troubleshoot what goes wrong across all the platforms. As soon as they changed to Ionic and Capacitor all the problems with developing on multiple platforms almost disappeared. The only problems that remained with Capacitor were due to differences in the device’s browser, but they were still way easier to troubleshoot and fix than NativeScript bugs.
- The power of a Reactive architecture as 50 people split into 7 feature teams were working together. By using NgRx the read/write separation made it simple to orchestrate state across the app in an event-based manner vs. creating hard coupling between the difference feature teams.
- The importance of standardizing the ways of working early on. For that reason, we developed the ten commandments of Angular development to make it simple for new developers to get on board with the ways of doing and stating simple principles for the most efficient Angular development.
Conclusion
In this post, I took you through my journey of Angular projects, which have created the knowledge foundation of a lot of the content you will find on this site (combined with learning from others and daily reading).
Do you want to become an Angular architect? Check out Angular Architect Accelerator.