You have unlimited access as a PRO member
You are receiving a free preview of 3 lessons
Your free preview as expired - please upgrade to PRO
Contents
Recent Posts
- Object Oriented Programming With TypeScript
- Angular Elements Advanced Techniques
- TypeScript - the Basics
- The Real State of JavaScript 2018
- Cloud Scheduler for Firebase Functions
- Testing Firestore Security Rules With the Emulator
- How to Use Git and Github
- Infinite Virtual Scroll With the Angular CDK
- Build a Group Chat With Firestore
- Async Await Pro Tips
Sortable Drag and Drop Lists in Firestore
Episode 142 written by Jeff DelaneyHealth Check: This lesson was last reviewed on and tested with these packages:
- Angular v6
- RxJS v6
- @angular/fire v5
- draggable v0.18.beta
Find an issue? Let's fix it
Source code for Sortable Drag and Drop Lists in Firestore on Github
Sortable drag-and-drop lists are not an easy feature to code from scratch - you need to juggle a bunch of DOM events and change styles on the elements gracefully to make it look good. Generally speaking, it’s not a good idea to reinvent the wheel when building a sortable list, but instead use a solid library like Shopify’s draggable. It today’s lesson, you will learn how to use draggable in Angular, then provide backend persistence for the items in Firestore.
Initial Setup
The app we’re building is a sortable list of emojis, where the data is an embedded array on a Firestore document.
This guide assumes that you’re working from an Angular app with @angular/fire installed. From there, we can install the @shopify/draggable. Specifically, we will be using the Sortable module built on top of draggable.
npm i @shopify/draggable |
Our feature will include (1) a smart component that handles the database interaction and (2) a directive that manages the sortable DOM elements.
ng g component emoji |
Sortable Directive
Our first step is to wrap the draggable library in Angular. Most of the UI functionality will happen magically out of the box, but we need to listen to custom events from draggable to know when to update the database. In our case, we want to run a Firestore update on the sortable:stop
event, which fires when the user has stopped dragging and the list is sorted.
The directive will take the initial document data via @Input
, then emit a sorted array out via @Output
. The parent component can listen to this event to know when a database write is needed.
import { |
In the next steps, we will put the directive to use in the HTML
<ul sortable (stop)="updateFirestore($event)"> |
Sorting the List in Firestore
In the following section, we will use a parent smart component to listen to the sort stop
event to trigger the database write.
Sorting the Entire Array
To sort an array in Firestore, we need to send the entire array in the data payload when running the update. Our directive already sends us the sorted array, so we just need execute the database write on the document.
import { Component, OnInit } from '@angular/core'; |
Updating Single Array Values in Firestore
Firebase recently introduced a two new methods for working with Array data in Firestore - arrayUnion
and arrayRemove
. This makes it easy to manage value uniqueness in an array field.
import { firestore } from 'firebase/app'; |
Making it Look Good
Draggable automatically toggles CSS classes on the elements, so we just need to write a little bit of CSS to make it look decent, but add CSS transition animations to these classes to really make them pop.
.draggable-container--is-dragging { |
The End
Using a library like Draggable adds a lot of magic to your app, but that’s often a tradeoff worth making. Encapsulating the code in a directive will means you can easily remove it or extend it with additional Angular functionality. You now have an easy starting point for building sortable lists in Firestore, let me know what you think on the comments or on Slack.