Introduction
I’ve been using Angular 1.x for building custom UI components and SPAs for SharePoint for years now. There’s a lot of rinse and repeat here, and over time my “stack” of open-source custom Directives and Services that make Angular such a powerful framework, have settled down to a few key ones that I wanted to highlight – hence this post.
Some may be wondering why am I still working almost exclusively with Angular 1.x? Why not Angular 2, or React, or Aurelia? A few reasons:
- It’s often already in use. Quite often a customer is already leveraging Angular 1.x in a custom masterpage, so it makes sense not to add another framework to the mix.
- Performance improvements are not a high priority. I work almost entirely with SharePoint Online. The classic ASP.NET pages served up there aren’t exactly blindingly fast to load, so Angular 1 (used carefully) doesn’t slow things down measurably. Will this change when SPFx finally GA’s? Of course! But in the meantime, Angular 1.x is very comfortable, which leads to…
- Familiarity = Productivity. Ramping up a custom application in SharePoint with Angular is now very quick to do. This is the whole “go with what you know well and can iterate fast on” approach to framework selection. Spend your time building out the logic of your app rather than fighting an unfamiliar framework.
- The absolute smorgasbord of community-produced libraries that enhance Angular. A lot of the major ones have Angular 2 versions, but there are some notable exceptions (highlighted below).
So here, in order of frequency of use, are the plugins that I go to time and time again. Check them out and star those github repos!
UI-Router
An awesome state-based routing service for Angular (and there are Angular 2 and React versions as well) – more widely used than the default Angular 1 router as it has a fantastic API which allows you resolve asynchronous data calls (via promises) before you transition to the state that needs it. This keeps your controllers/components light and clean. I use this every custom webpart/SPA I build that has more than one view (which is almost all of them).
If you need modals in your app, you can add in the uib-modal extension that allows UI-Bootstrap modals to be declared as state in your UI-Router state config. Great for deep linking through to modal windows!
Angular Formly
Sick of labouring over large form templates? They are time consuming to wire up and maintain – that’s a lot of markup! Formly allows you to declare your form fields in JavaScript instead. This allows for a lot more control and being able to generate the UI on the fly at run time is a killer feature (that I haven’t done enough with to date!). I hope to have another post on this topic very soon…
Formly makes using custom controls / directives in forms really easy and gives you uniform validation rules over all of them. It’s also wonderfully extensible – there’s so much you can do with it, once you learn the basics. I put off trying it for AGES and now I wouldn’t be without it – if you have any user input in your Angular app, do yourself a favour and use Formly!
AG-Grid
The best JavaScript grid component. Period. Like all libraries I’ve mentioned so far, this one is also not just for Angular (this one supports nearly all of the major frameworks, including Aurelia and Vue). There’s a Free and an Enterprise version with a lot of extra bells and whistles. I haven’t had to shell out for Enterprise yet – Free is very fully featured as is. If you have a table of data in your app – you should give this a try for all but the most simple scenarios.
Angular-Gantt
Here’s the first Angular 1 only library in my toolbox. Makes creating complex Gantt-chart interfaces if not dead easy, at least feasible! I shudder to think what I nightmare it would be to write this kind of functionality from scratch…
There’s loads of features here, just like the other libararies listed.
Angular-Wizard
Another Angular 1-only (although similar Angular 2 projects exist). Great little wizard form directive that allows you to declare steps of your wizard declaratively in your template, or when teamed up with Formly, in your controller. The latter allows you to create dynamic wizard steps by filtering the questions in the next step based on the response to the previous (once again – need to document this in another post in future).
A few extra tricks for SharePoint…
A few other more generic practices when slinging Angular in SharePoint:
- Don’t be afraid to use $q to wrap your own promises – yes it is overused in a lot of example code on Stack Overflow (hint: if you are calling the $http service, you don’t need $q, just return the result of the $http call), but it’s great if you want/need to use CSOM. Just wrap the result of executeQueryAsync in a promise’s resolve method and you’ve got a far cleaner implementation (no callbacks when you utilise it), so it’s easily packaged up in a service.
- Create a reusable service layer – lots of people don’t bother to use Angular services, as most example code just keeps the $http calls in the controller for simplicity. Keep all your REST and CSOM calls to interact with SharePoint in a service module and you’ll get a lot more reuse of your code from application to application. Ideally, use ui-router to resolve the promises from your service before the controller is even initialised (as mentioned above).
- Use Widget Wrangler for hosting your Angular apps in SharePoint pages– this handles all your script dependencies cleanly and lets you host in a ScriptEditor webpart (easily deployed with PnP PowerShell).
- Think about caching your data or real-time sync – the excellent Angular-Cache is great for client-side caching of data and if your application’s data is frequently updated, you may want to consider a real-time data option to enhance the solution and prevent the need for page refreshes (another post on this coming soon too), such as Firebase or GunJS.
- Azure Functions-All-The-Things! No more PowerShell running in a scheduled task on a VM for background processing. There is a better (and even cheaper) way.
I hope some people find this useful. Please leave a comment if you’ve got some other Angular-goodness you’d like to share!