TLDR – A todo/task list built with Angular 9. This app utilizes Angular Material’s drag and drop out of box and with the help of NgRx, the UI can maintain its previous state on page refresh.
Features
- Provide sorting by table columns and searching.
- Add sorting by multiple columns and persist the sorting on refresh.
- Add the ability to drag and drop columns to reorder them using the native Angular cdk drag and drop.
- Add ability to manually resize the columns by dragging with the mouse.
- Use Angular, RxJs and NgRx for state management.
Demo
Conclusions
Easy
Filtering a list of tasks leveraging a search bar was straightforward enough, thankfully. Check out the pipe and how that ties back into the ngModel
on the input element for further details. My implementation is for the most part 1:1 from this Stackblitz demo.
Medium
Imagine an excel spreadsheet in which you can resize the cells (see the purple drag handles on the To Do column). It’s a similar ask here.
At the time of this writing, Angular Material does not fully support a way to resize elements. It was asked in 2019 but I didn’t find anything from the current documentation. I found this ngx-cdk-drag-resize demo to be a good starting path leveraging Angular’s ElementRef API out of box.
The other gotcha was sorting by order. AngularJS did it but Angular’s core argument for not including that feature in their current API is simply for performance. Your options are limited to creating your own custom pipe or having your component take on that responsibility. In my case, the dynamicSort() function on my home page component is what I used to sort order attributes in ascending order.
Hard
Saving the order of drag and drop. Saving the order on drag and drop and distinguishing between to do and done. Saving the order on drag and drop, distinguishing between to do and done, refresh the page and ensuring the previous state was maintained.
That. Was. Hard.
My initial thought was to save via localStorage but having localStorage fly on its own was brittle and often caused inconsistencies when ad hoc testing. I needed a strict approach that could thoughtfully manage the user interaction, namely @ngrx/store because at its core everything is immutable. Acknowledging that very rule was hard to embrace but in my opinion it’s the way to go when creating insanely stable Angular web apps.
In my case, I used a combination of reducers, actions and effects.
It took me the better of two weeks just to understand NgRx on an elementary level so here’s my tip on how to get through these dense concepts. My suggestion assumes you’ve used Angular on a consistent basis and you’re looking to add on top of your existing knowledge of that.
If you use Angular regularly then you’re familiar with the green action below called Components. You might even be communicating with a backend system which means the other green action, Services and that blue document, APIs are also part of your web app flow. An abundance of Angular tutorials are demonstrated with just these ingredients alone. So if you’re looking to spice it up with NgRx, add the following steps below.
Step 1
Review these additional actions and employ them where needed: Store, Selectors, Reducers, Actions and Effects.
Step 2
Follow the arrows. At all times, follow the arrows.
Please feel free to fork this into your own creation.
And remember, when all else fails…StackOverflow. 😉
Aloha. 🤙🏾
Additional Resources
- How To Build an App With Drag and Drop With Angular (original source of inspiration sans JSON mock server)
- 5 Things I wish I knew about the CDK’s Drag & Drop (when I got frustrated with CDK)
- Adding NgRx to Your Existing Applications (adding NgRx to the original source)
- Save order on page refresh of cdkDrag, cdkDropList Angular Material (when I needed consultation from the StackOverflow Gods)