Build a drag-n-drop list with Firestore using Shopify's draggable library. https://angularfirebase.com/lessons/sortable-drag-and-drop-lists-in-firestore/

- Draggable https://shopify.github.io/draggable/
- Firestore https://firebase.google.com/docs/firestore/
2024-02-04T07:12:13.457Z
nova-2
2-general-nova
2024-01-09.29447
30089e05-99d1-4376-b32e-c263170674af
5ac6728c-b9bd-44b4-8af9-1b2c2cf02fef
d79f2a15b374d865e9a4d0946aa5f5a7d1bcfcf058f1eff332333c577a344328
67875a7f-c9c4-48a0-aa55-5bdb8a91c34a
deprecated
One of the more challenging features to build in a web application is a drag and drop sortable list, and it's even more challenging if you need to persist the data in a back end database.
Instead of trying to reinvent the wheel, we're going to use a library called draggable that's maintained by Shopify.
It's relatively lightweight and we can wrap it in Angular to make drag and drop features, much more enjoyable to code.
If you're new to the channel, like and subscribe, and you can find the source code on angular firebase.com.
What we're building today is a sortable list of emojis, the user can add or remove items from the list and they can drag items to change the order and have that order be saved in the database.
This is a pretty complex thing to do from scratch because if you notice when we drag an item, it creates a mirror of the original element and toggles a whole bunch of CSS classes on the container and the individual items themselves.
Draggable will make this feature surprisingly easy, but also give us enough flexibility to build something unique.
In addition, Firestore recently released a couple of new helper methods that make it easy to add or remove elements from an array.
So We'll take a look at those as well, but the first thing you need to get started is an Angular app with AngularFire installed.
From there, we'll go to the command line and install draggable with npm.
There are 2 main elements to this demo.
1st, we have a smart component, which is our emoji component, and it handles retrieving items from the database and can also add or remove new emojis to the list.
Then we have a directive called sortable, which I'm going to call our dumb component because a directive is essentially just a component that doesn't have a custom HTML template.
It can do pretty much everything a component can do, but instead it attaches itself to a host element and extends the functionality of that element.
When working with sortable list like this, you'll usually attach this to an unordered list and then have your list items be sortable within it.
We'll start by building out the directive and you'll notice that we're importing a bunch of things here from Angular core.
And this is also where we'll import sortable from Shopify draggable.
We're going to implement the AfterView init lifecycle hook on this directive just so we know that all of the children elements are available once we start running the sortable code on it.
Then we're going to have it emit a custom event that has the new order of the sorted items.
In order to be able to do that, we first need to pass in the initial items, which we'll do with an input property on the directive.
Then after the items have been sorted, we'll emit our own custom event by using the output decorator and an event emitter.
There's quite a few different events you can track here.
So I've commented those out in case you need them.
The only one we need is when the actual sorting has been finished.
Then we'll inject element ref in the constructor, which will give us access to the DOM element, which in this case should be an unordered list.
So once that's done, we can initialize sortable by creating a new instance of the class and then passing it the element ref native element.
Then it takes a second argument with some options.
We're going to specify the draggable elements as the list items within that list.
The draggable library is going to emit its own custom events which we can intercept here to emit our own custom event that will have the newly sorted list.
Again, there are multiple custom events that you might need, but the one that we care about is sortable stop.
At that point, we know the user is done sorting the list.
So we'll go ahead and take the initial array, reorder it, and then emit that out through our custom event emitter so the parent component can listen to it and handle it accordingly.
The sortable stop event keeps track of all the elements in the list, and it will give us the new index and the old index of the item that was moved.
So we'll use this method as just a context for mutating the original data.
So what we can do here is take the original data as our starting point, then we can splice off the old index and then resplice it back into the new index.
Once we have the array in the format that we want, we can go ahead and emit it out as the value from our custom event.
In the next step, we'll have the parent component listen to this event and then update the Firestore database with the new value.
Now that we have our directive finished, we'll go into the HTML for the component.
We can just insert it into an unordered list and that will give us access to both its input properties as well as its output properties.
The data that we read from the database will be an observable.
So I'm doing an n g f statement here with the document and setting that document as a template variable.
Then we'll pass that to the data input on the directive.
And then lastly, we will listen to our custom stop event, and then we'll write an event handler that will update the database when that fires.
Now we can loop over the array of emojis and render a list item for each one.
Then while we're here in the HTML, I wanna add a couple of extra things.
First, I'll add another button here that the user can click to remove an item from an array.
Then I'll move outside of our loop and add an additional method that we can use to add an additional emoji to the array.
And these are mostly just so I can show you the new array methods in Firestore.
Now we'll go into our component typescript and finish this feature out.
I am importing Angular Firestore and then also Firestore directly from the Firebase app name space.
We can inject AngularFirestore in the constructor, and then we'll set up one variable for our document reference so we can make updates on it, and then another one for the actual observable data.
Then I'll go ahead and define those during n g on init.
For now, I'm just going to point to a dummy document that I have saved in the emojis collection.
Then we can define our observable of that document by calling value changes on the reference.
Here's what that document actually looks like in the database.
We have an array data structure here called faves and it currently has 3 different emojis in it.
When the user sorts this list, we can update the array in Firestore by simply making a reference to the document and calling update with the new array.
We set up the Event Emitter in the directive to send the newly sorted array.
So this is all the code we need to update the document in Firestore.
But if you want to add a single item to the array, one way to do that is with the new Firestore array union method which will ensure that a unique item is added to the existing array.
This is really nice when you want to enforce uniqueness in the array which is exactly what we wanna do here.
So we'll call Firestore field value array union and then pass in the element that we want to add to it.
If that value already exists in the array, then nothing will happen.
But otherwise, it will append that item to the end of the array.
You can also remove items from the array, which is also very useful because a lot of times you don't already know the index of the item and you just want it gone.
So Firestore field value array remove will find that element in the array and remove it.
So that takes care of all of our typescript code, but in order to make drag and drop look good, you're going to have to spend quite a bit of time in your CSS styling.
One of the cool things about draggable is that it will add a whole bunch of different CSS to your elements depending on what state they're in within the draggable list.
For example, we might want to add a style to the container element when it's being dragged like a blue border.
Then the source element that's being dragged, we might wanna make that a lighter color and scale it down a little bit.
Then once the item is placed, we'll go ahead and color the background to green and draggable will remove this class after a second so we can get that green flashing effect when the item is set.
And another cool thing draggable does is that it creates a mirror element item is set, and another cool thing draggable does is that it creates a mirror element of the item that was selected.
So you can use that to build out a more complex and to handle things like animations.
When we go to our demo you can see that a lot of different classes are being swapped out on the elements as we drag things around here.
And as you can imagine doing this kind of stuff reliably from scratch takes a lot of time and effort, so using a library like draggable is just going to make your life a lot easier.
I'm gonna go ahead and wrap up the video there.
If it helped you, please like and subscribe.
And if you want to take your development to the next level, consider becoming a pro member at angularfirebase.com.
You'll you'll get access to all kinds of advanced exclusive content designed to help you build and ship your app faster.
Thanks for watching, and I'll talk to you soon.

Speaker 0: One of the more challenging features to build in a web application is a drag and drop sortable list, and it's even more challenging if you need to persist the data in a back end database. Instead of trying to reinvent the wheel, we're going to use a library called draggable that's maintained by Shopify. It's relatively lightweight and we can wrap it in Angular to make drag and drop features, much more enjoyable to code. If you're new to the channel, like and subscribe, and you can find the source code on angular firebase.com. What we're building today is a sortable list of emojis, the user can add or remove items from the list and they can drag items to change the order and have that order be saved in the database.

This is a pretty complex thing to do from scratch because if you notice when we drag an item, it creates a mirror of the original element and toggles a whole bunch of CSS classes on the container and the individual items themselves. Draggable will make this feature surprisingly easy, but also give us enough flexibility to build something unique. In addition, Firestore recently released a couple of new helper methods that make it easy to add or remove elements from an array. So We'll take a look at those as well, but the first thing you need to get started is an Angular app with AngularFire installed. From there, we'll go to the command line and install draggable with npm.

There are 2 main elements to this demo. 1st, we have a smart component, which is our emoji component, and it handles retrieving items from the database and can also add or remove new emojis to the list. Then we have a directive called sortable, which I'm going to call our dumb component because a directive is essentially just a component that doesn't have a custom HTML template. It can do pretty much everything a component can do, but instead it attaches itself to a host element and extends the functionality of that element. When working with sortable list like this, you'll usually attach this to an unordered list and then have your list items be sortable within it.

We'll start by building out the directive and you'll notice that we're importing a bunch of things here from Angular core. And this is also where we'll import sortable from Shopify draggable. We're going to implement the AfterView init lifecycle hook on this directive just so we know that all of the children elements are available once we start running the sortable code on it. Then we're going to have it emit a custom event that has the new order of the sorted items. In order to be able to do that, we first need to pass in the initial items, which we'll do with an input property on the directive.

Then after the items have been sorted, we'll emit our own custom event by using the output decorator and an event emitter. There's quite a few different events you can track here. So I've commented those out in case you need them. The only one we need is when the actual sorting has been finished. Then we'll inject element ref in the constructor, which will give us access to the DOM element, which in this case should be an unordered list.

So once that's done, we can initialize sortable by creating a new instance of the class and then passing it the element ref native element. Then it takes a second argument with some options. We're going to specify the draggable elements as the list items within that list. The draggable library is going to emit its own custom events which we can intercept here to emit our own custom event that will have the newly sorted list. Again, there are multiple custom events that you might need, but the one that we care about is sortable stop.

At that point, we know the user is done sorting the list. So we'll go ahead and take the initial array, reorder it, and then emit that out through our custom event emitter so the parent component can listen to it and handle it accordingly. The sortable stop event keeps track of all the elements in the list, and it will give us the new index and the old index of the item that was moved. So we'll use this method as just a context for mutating the original data. So what we can do here is take the original data as our starting point, then we can splice off the old index and then resplice it back into the new index.

Once we have the array in the format that we want, we can go ahead and emit it out as the value from our custom event. In the next step, we'll have the parent component listen to this event and then update the Firestore database with the new value. Now that we have our directive finished, we'll go into the HTML for the component. We can just insert it into an unordered list and that will give us access to both its input properties as well as its output properties. The data that we read from the database will be an observable.

So I'm doing an n g f statement here with the document and setting that document as a template variable. Then we'll pass that to the data input on the directive. And then lastly, we will listen to our custom stop event, and then we'll write an event handler that will update the database when that fires. Now we can loop over the array of emojis and render a list item for each one. Then while we're here in the HTML, I wanna add a couple of extra things.

First, I'll add another button here that the user can click to remove an item from an array. Then I'll move outside of our loop and add an additional method that we can use to add an additional emoji to the array. And these are mostly just so I can show you the new array methods in Firestore. Now we'll go into our component typescript and finish this feature out. I am importing Angular Firestore and then also Firestore directly from the Firebase app name space.

We can inject AngularFirestore in the constructor, and then we'll set up one variable for our document reference so we can make updates on it, and then another one for the actual observable data. Then I'll go ahead and define those during n g on init. For now, I'm just going to point to a dummy document that I have saved in the emojis collection. Then we can define our observable of that document by calling value changes on the reference. Here's what that document actually looks like in the database.

We have an array data structure here called faves and it currently has 3 different emojis in it. When the user sorts this list, we can update the array in Firestore by simply making a reference to the document and calling update with the new array. We set up the Event Emitter in the directive to send the newly sorted array. So this is all the code we need to update the document in Firestore. But if you want to add a single item to the array, one way to do that is with the new Firestore array union method which will ensure that a unique item is added to the existing array.

This is really nice when you want to enforce uniqueness in the array which is exactly what we wanna do here. So we'll call Firestore field value array union and then pass in the element that we want to add to it. If that value already exists in the array, then nothing will happen. But otherwise, it will append that item to the end of the array. You can also remove items from the array, which is also very useful because a lot of times you don't already know the index of the item and you just want it gone.

So Firestore field value array remove will find that element in the array and remove it. So that takes care of all of our typescript code, but in order to make drag and drop look good, you're going to have to spend quite a bit of time in your CSS styling. One of the cool things about draggable is that it will add a whole bunch of different CSS to your elements depending on what state they're in within the draggable list. For example, we might want to add a style to the container element when it's being dragged like a blue border. Then the source element that's being dragged, we might wanna make that a lighter color and scale it down a little bit.

Then once the item is placed, we'll go ahead and color the background to green and draggable will remove this class after a second so we can get that green flashing effect when the item is set. And another cool thing draggable does is that it creates a mirror element item is set, and another cool thing draggable does is that it creates a mirror element of the item that was selected. So you can use that to build out a more complex and to handle things like animations. When we go to our demo you can see that a lot of different classes are being swapped out on the elements as we drag things around here. And as you can imagine doing this kind of stuff reliably from scratch takes a lot of time and effort, so using a library like draggable is just going to make your life a lot easier.

I'm gonna go ahead and wrap up the video there. If it helped you, please like and subscribe. And if you want to take your development to the next level, consider becoming a pro member at angularfirebase.com. You'll you'll get access to all kinds of advanced exclusive content designed to help you build and ship your app faster. Thanks for watching, and I'll talk to you soon.
One of the more challenging features to build in a web application is a drag and drop sortable list, and it's even more challenging if you need to persist the data in a back end database. Instead of trying to reinvent the wheel, we're going to use a library called draggable that's maintained by Shopify.
databases
It's relatively lightweight and we can wrap it in Angular to make drag and drop features, much more enjoyable to code. If you're new to the channel, like and subscribe, and you can find the source code on angular firebase.com. What we're building today is a sortable list of emojis, the user can add or remove items from the list and they can drag items to change the order and have that order be saved in the database.
This is a pretty complex thing to do from scratch because if you notice when we drag an item, it creates a mirror of the original element and toggles a whole bunch of CSS classes on the container and the individual items themselves. Draggable will make this feature surprisingly easy, but also give us enough flexibility to build something unique.
crafts
toys
In addition, Firestore recently released a couple of new helper methods that make it easy to add or remove elements from an array.
So We'll take a look at those as well, but the first thing you need to get started is an Angular app with AngularFire installed. From there, we'll go to the command line and install draggable with npm. There are 2 main elements to this demo. 1st, we have a smart component, which is our emoji component, and it handles retrieving items from the database and can also add or remove new emojis to the list.
animation
Then we have a directive called sortable, which I'm going to call our dumb component because a directive is essentially just a component that doesn't have a custom HTML template. It can do pretty much everything a component can do, but instead it attaches itself to a host element and extends the functionality of that element. When working with sortable list like this, you'll usually attach this to an unordered list and then have your list items be sortable within it. We'll start by building out the directive and you'll notice that we're importing a bunch of things here from Angular core. And this is also where we'll import sortable from Shopify draggable. We're going to implement the AfterView init lifecycle hook on this directive just so we know that all of the children elements are available once we start running the sortable code on it. Then we're going to have it emit a custom event that has the new order of the sorted items. In order to be able to do that, we first need to pass in the initial items, which we'll do with an input property on the directive.
Then after the items have been sorted, we'll emit our own custom event by using the output decorator and an event emitter. There's quite a few different events you can track here. So I've commented those out in case you need them. The only one we need is when the actual sorting has been finished.
home improvement
Then we'll inject element ref in the constructor, which will give us access to the DOM element, which in this case should be an unordered list. So once that's done, we can initialize sortable by creating a new instance of the class and then passing it the element ref native element. Then it takes a second argument with some options. We're going to specify the draggable elements as the list items within that list. The draggable library is going to emit its own custom events which we can intercept here to emit our own custom event that will have the newly sorted list. Again, there are multiple custom events that you might need, but the one that we care about is sortable stop. At that point, we know the user is done sorting the list. So we'll go ahead and take the initial array, reorder it, and then emit that out through our custom event emitter so the parent component can listen to it and handle it accordingly.
The sortable stop event keeps track of all the elements in the list, and it will give us the new index and the old index of the item that was moved. So we'll use this method as just a context for mutating the original data. So what we can do here is take the original data as our starting point, then we can splice off the old index and then resplice it back into the new index. Once we have the array in the format that we want, we can go ahead and emit it out as the value from our custom event.
data
In the next step, we'll have the parent component listen to this event and then update the Firestore database with the new value. Now that we have our directive finished, we'll go into the HTML for the component.
We can just insert it into an unordered list and that will give us access to both its input properties as well as its output properties. The data that we read from the database will be an observable. So I'm doing an n g f statement here with the document and setting that document as a template variable. Then we'll pass that to the data input on the directive. And then lastly, we will listen to our custom stop event, and then we'll write an event handler that will update the database when that fires.
data
data management
databases
documentation
programming
Now we can loop over the array of emojis and render a list item for each one. Then while we're here in the HTML, I wanna add a couple of extra things. First, I'll add another button here that the user can click to remove an item from an array. Then I'll move outside of our loop and add an additional method that we can use to add an additional emoji to the array. And these are mostly just so I can show you the new array methods in Firestore. Now we'll go into our component typescript and finish this feature out. I am importing Angular Firestore and then also Firestore directly from the Firebase app name space. We can inject AngularFirestore in the constructor, and then we'll set up one variable for our document reference so we can make updates on it, and then another one for the actual observable data.
Then I'll go ahead and define those during n g on init. For now, I'm just going to point to a dummy document that I have saved in the emojis collection. Then we can define our observable of that document by calling value changes on the reference. Here's what that document actually looks like in the database. We have an array data structure here called faves and it currently has 3 different emojis in it. When the user sorts this list, we can update the array in Firestore by simply making a reference to the document and calling update with the new array.
documentation
databases
data
We set up the Event Emitter in the directive to send the newly sorted array. So this is all the code we need to update the document in Firestore. But if you want to add a single item to the array, one way to do that is with the new Firestore array union method which will ensure that a unique item is added to the existing array. This is really nice when you want to enforce uniqueness in the array which is exactly what we wanna do here. So we'll call Firestore field value array union and then pass in the element that we want to add to it. If that value already exists in the array, then nothing will happen. But otherwise, it will append that item to the end of the array. You can also remove items from the array, which is also very useful because a lot of times you don't already know the index of the item and you just want it gone. So Firestore field value array remove will find that element in the array and remove it. So that takes care of all of our typescript code, but in order to make drag and drop look good, you're going to have to spend quite a bit of time in your CSS styling. One of the cool things about draggable is that it will add a whole bunch of different CSS to your elements depending on what state they're in within the draggable list. For example, we might want to add a style to the container element when it's being dragged like a blue border. Then the source element that's being dragged, we might wanna make that a lighter color and scale it down a little bit. Then once the item is placed, we'll go ahead and color the background to green and draggable will remove this class after a second so we can get that green flashing effect when the item is set.
And another cool thing draggable does is that it creates a mirror element item is set, and another cool thing draggable does is that it creates a mirror element of the item that was selected. So you can use that to build out a more complex and to handle things like animations. When we go to our demo you can see that a lot of different classes are being swapped out on the elements as we drag things around here. And as you can imagine doing this kind of stuff reliably from scratch takes a lot of time and effort, so using a library like draggable is just going to make your life a lot easier. I'm gonna go ahead and wrap up the video there. If it helped you, please like and subscribe. And if you want to take your development to the next level, consider becoming a pro member at angularfirebase.com. You'll you'll get access to all kinds of advanced exclusive content designed to help you build and ship your app faster. Thanks for watching, and I'll talk to you soon.
software
youtube
animation
internet
streaming
software development
toys
multimedia
video gaming
robotics
One of the more challenging features to build in a web application is a drag and drop sortable list, and it's even more challenging if you need to persist the data in a back end database. Instead of trying to reinvent the wheel, we're going to use a library called draggable that's maintained by Shopify. It's relatively lightweight and we can wrap it in Angular to make drag and drop features, much more enjoyable to code. If you're new to the channel, like and subscribe, and you can find the source code on angular firebase.com. What we're building today is a sortable list of emojis, the user can add or remove items from the list and they can drag items to change the order and have that order be saved in the database. This is a pretty complex thing to do from scratch because if you notice when we drag an item, it creates a mirror of the original element and toggles a whole bunch of CSS classes on the container and the individual items themselves. Draggable will make this feature surprisingly easy, but also give us enough flexibility to build something unique. In addition, Firestore recently released a couple of new helper methods that make it easy to add or remove elements from an array. So We'll take a look at those as well, but the first thing you need to get started is an Angular app with AngularFire installed. From there, we'll go to the command line and install draggable with npm. There are 2 main elements to this demo. 1st, we have a smart component, which is our emoji component, and it handles retrieving items from the database and can also add or remove new emojis to the list. Then we have a directive called sortable, which I'm going to call our dumb component because a directive is essentially just a component that doesn't have a custom HTML template. It can do pretty much everything a component can do, but instead it attaches itself to a host element and extends the functionality of that element. When working with sortable list like this, you'll usually attach this to an unordered list and then have your list items be sortable within it. We'll start by building out the directive and you'll notice that we're importing a bunch of things here from Angular core. And this is also where we'll import sortable from Shopify draggable. We're going to implement the AfterView init lifecycle hook on this directive just so we know that all of the children elements are available once we start running the sortable code on it. Then we're going to have it emit a custom event that has the new order of the sorted items. In order to be able to do that, we first need to pass in the initial items, which we'll do with an input property on the directive. Then after the items have been sorted, we'll emit our own custom event by using the output decorator and an event emitter. There's quite a few different events you can track here. So I've commented those out in case you need them. The only one we need is when the actual sorting has been finished. Then we'll inject element ref in the constructor, which will give us access to the DOM element, which in this case should be an unordered list. So once that's done, we can initialize sortable by creating a new instance of the class and then passing it the element ref native element. Then it takes a second argument with some options. We're going to specify the draggable elements as the list items within that list. The draggable library is going to emit its own custom events which we can intercept here to emit our own custom event that will have the newly sorted list. Again, there are multiple custom events that you might need, but the one that we care about is sortable stop. At that point, we know the user is done sorting the list. So we'll go ahead and take the initial array, reorder it, and then emit that out through our custom event emitter so the parent component can listen to it and handle it accordingly. The sortable stop event keeps track of all the elements in the list, and it will give us the new index and the old index of the item that was moved. So we'll use this method as just a context for mutating the original data. So what we can do here is take the original data as our starting point, then we can splice off the old index and then resplice it back into the new index. Once we have the array in the format that we want, we can go ahead and emit it out as the value from our custom event. In the next step, we'll have the parent component listen to this event and then update the Firestore database with the new value. Now that we have our directive finished, we'll go into the HTML for the component. We can just insert it into an unordered list and that will give us access to both its input properties as well as its output properties. The data that we read from the database will be an observable. So I'm doing an n g f statement here with the document and setting that document as a template variable. Then we'll pass that to the data input on the directive. And then lastly, we will listen to our custom stop event, and then we'll write an event handler that will update the database when that fires. Now we can loop over the array of emojis and render a list item for each one. Then while we're here in the HTML, I wanna add a couple of extra things. First, I'll add another button here that the user can click to remove an item from an array. Then I'll move outside of our loop and add an additional method that we can use to add an additional emoji to the array. And these are mostly just so I can show you the new array methods in Firestore. Now we'll go into our component typescript and finish this feature out. I am importing Angular Firestore and then also Firestore directly from the Firebase app name space. We can inject AngularFirestore in the constructor, and then we'll set up one variable for our document reference so we can make updates on it, and then another one for the actual observable data. Then I'll go ahead and define those during n g on init. For now, I'm just going to point to a dummy document that I have saved in the emojis collection. Then we can define our observable of that document by calling value changes on the reference. Here's what that document actually looks like in the database. We have an array data structure here called faves and it currently has 3 different emojis in it. When the user sorts this list, we can update the array in Firestore by simply making a reference to the document and calling update with the new array. We set up the Event Emitter in the directive to send the newly sorted array. So this is all the code we need to update the document in Firestore. But if you want to add a single item to the array, one way to do that is with the new Firestore array union method which will ensure that a unique item is added to the existing array. This is really nice when you want to enforce uniqueness in the array which is exactly what we wanna do here. So we'll call Firestore field value array union and then pass in the element that we want to add to it. If that value already exists in the array, then nothing will happen. But otherwise, it will append that item to the end of the array. You can also remove items from the array, which is also very useful because a lot of times you don't already know the index of the item and you just want it gone. So Firestore field value array remove will find that element in the array and remove it. So that takes care of all of our typescript code, but in order to make drag and drop look good, you're going to have to spend quite a bit of time in your CSS styling. One of the cool things about draggable is that it will add a whole bunch of different CSS to your elements depending on what state they're in within the draggable list. For example, we might want to add a style to the container element when it's being dragged like a blue border. Then the source element that's being dragged, we might wanna make that a lighter color and scale it down a little bit. Then once the item is placed, we'll go ahead and color the background to green and draggable will remove this class after a second so we can get that green flashing effect when the item is set. And another cool thing draggable does is that it creates a mirror element item is set, and another cool thing draggable does is that it creates a mirror element of the item that was selected. So you can use that to build out a more complex and to handle things like animations. When we go to our demo you can see that a lot of different classes are being swapped out on the elements as we drag things around here. And as you can imagine doing this kind of stuff reliably from scratch takes a lot of time and effort, so using a library like draggable is just going to make your life a lot easier. I'm gonna go ahead and wrap up the video there. If it helped you, please like and subscribe. And if you want to take your development to the next level, consider becoming a pro member at angularfirebase.com. You'll you'll get access to all kinds of advanced exclusive content designed to help you build and ship your app faster. Thanks for watching, and I'll talk to you soon.
One
one
of
of
the
the
more
more
challenging
challenging
features
features
to
to
build
build
in
in
a
a
web
web
application
application
is
is
a
a
drag
drag
and
and
drop
drop
sortable
sortable
list,
list
and
and
it's
it's
even
even
more
more
challenging
challenging
if
if
you
you
need
need
to
to
persist
persist
the
the
data
data
in
in
a
a
back
back
end
end
database.
database
Instead
instead
of
of
trying
trying
to
to
reinvent
reinvent
the
the
wheel,
wheel
we're
we're
going
going
to
to
use
use
a
a
library
library
called
called
draggable
draggable
that's
that's
maintained
maintained
by
by
Shopify.
shopify
It's
it's
relatively
relatively
lightweight
lightweight
and
and
we
we
can
can
wrap
wrap
it
it
in
in
Angular
angular
to
to
make
make
drag
drag
and
and
drop
drop
features,
features
much
much
more
more
enjoyable
enjoyable
to
to
code.
code
If
if
you're
you're
new
new
to
to
the
the
channel,
channel
like
like
and
and
subscribe,
subscribe
and
and
you
you
can
can
find
find
the
the
source
source
code
code
on
on
angular
angular
firebase.com.
firebase.com
What
what
we're
we're
building
building
today
today
is
is
a
a
sortable
sortable
list
list
of
of
emojis,
emojis
the
the
user
user
can
can
add
add
or
or
remove
remove
items
items
from
from
the
the
list
list
and
and
they
they
can
can
drag
drag
items
items
to
to
change
change
the
the
order
order
and
and
have
have
that
that
order
order
be
be
saved
saved
in
in
the
the
database.
database
This
this
is
is
a
a
pretty
pretty
complex
complex
thing
thing
to
to
do
do
from
from
scratch
scratch
because
because
if
if
you
you
notice
notice
when
when
we
we
drag
drag
an
an
item,
item
it
it
creates
creates
a
a
mirror
mirror
of
of
the
the
original
original
element
element
and
and
toggles
toggles
a
a
whole
whole
bunch
bunch
of
of
CSS
css
classes
classes
on
on
the
the
container
container
and
and
the
the
individual
individual
items
items
themselves.
themselves
Draggable
draggable
will
will
make
make
this
this
feature
feature
surprisingly
surprisingly
easy,
easy
but
but
also
also
give
give
us
us
enough
enough
flexibility
flexibility
to
to
build
build
something
something
unique.
unique
In
in
addition,
addition
Firestore
firestore
recently
recently
released
released
a
a
couple
couple
of
of
new
new
helper
helper
methods
methods
that
that
make
make
it
it
easy
easy
to
to
add
add
or
or
remove
remove
elements
elements
from
from
an
an
array.
array
So
so
We'll
we'll
take
take
a
a
look
look
at
at
those
those
as
as
well,
well
but
but
the
the
first
first
thing
thing
you
you
need
need
to
to
get
get
started
started
is
is
an
an
Angular
angular
app
app
with
with
AngularFire
angularfire
installed.
installed
From
from
there,
there
we'll
we'll
go
go
to
to
the
the
command
command
line
line
and
and
install
install
draggable
draggable
with
with
npm.
npm
There
there
are
are
2
2
main
main
elements
elements
to
to
this
this
demo.
demo
1st,
1st
we
we
have
have
a
a
smart
smart
component,
component
which
which
is
is
our
our
emoji
emoji
component,
component
and
and
it
it
handles
handles
retrieving
retrieving
items
items
from
from
the
the
database
database
and
and
can
can
also
also
add
add
or
or
remove
remove
new
new
emojis
emojis
to
to
the
the
list.
list
Then
then
we
we
have
have
a
a
directive
directive
called
called
sortable,
sortable
which
which
I'm
i'm
going
going
to
to
call
call
our
our
dumb
dumb
component
component
because
because
a
a
directive
directive
is
is
essentially
essentially
just
just
a
a
component
component
that
that
doesn't
doesn't
have
have
a
a
custom
custom
HTML
html
template.
template
It
it
can
can
do
do
pretty
pretty
much
much
everything
everything
a
a
component
component
can
can
do,
do
but
but
instead
instead
it
it
attaches
attaches
itself
itself
to
to
a
a
host
host
element
element
and
and
extends
extends
the
the
functionality
functionality
of
of
that
that
element.
element
When
when
working
working
with
with
sortable
sortable
list
list
like
like
this,
this
you'll
you'll
usually
usually
attach
attach
this
this
to
to
an
an
unordered
unordered
list
list
and
and
then
then
have
have
your
your
list
list
items
items
be
be
sortable
sortable
within
within
it.
it
We'll
we'll
start
start
by
by
building
building
out
out
the
the
directive
directive
and
and
you'll
you'll
notice
notice
that
that
we're
we're
importing
importing
a
a
bunch
bunch
of
of
things
things
here
here
from
from
Angular
angular
core.
core
And
and
this
this
is
is
also
also
where
where
we'll
we'll
import
import
sortable
sortable
from
from
Shopify
shopify
draggable.
draggable
We're
we're
going
going
to
to
implement
implement
the
the
AfterView
afterview
init
init
lifecycle
lifecycle
hook
hook
on
on
this
this
directive
directive
just
just
so
so
we
we
know
know
that
that
all
all
of
of
the
the
children
children
elements
elements
are
are
available
available
once
once
we
we
start
start
running
running
the
the
sortable
sortable
code
code
on
on
it.
it
Then
then
we're
we're
going
going
to
to
have
have
it
it
emit
emit
a
a
custom
custom
event
event
that
that
has
has
the
the
new
new
order
order
of
of
the
the
sorted
sorted
items.
items
In
in
order
order
to
to
be
be
able
able
to
to
do
do
that,
that
we
we
first
first
need
need
to
to
pass
pass
in
in
the
the
initial
initial
items,
items
which
which
we'll
we'll
do
do
with
with
an
an
input
input
property
property
on
on
the
the
directive.
directive
Then
then
after
after
the
the
items
items
have
have
been
been
sorted,
sorted
we'll
we'll
emit
emit
our
our
own
own
custom
custom
event
event
by
by
using
using
the
the
output
output
decorator
decorator
and
and
an
an
event
event
emitter.
emitter
There's
there's
quite
quite
a
a
few
few
different
different
events
events
you
you
can
can
track
track
here.
here
So
so
I've
i've
commented
commented
those
those
out
out
in
in
case
case
you
you
need
need
them.
them
The
the
only
only
one
one
we
we
need
need
is
is
when
when
the
the
actual
actual
sorting
sorting
has
has
been
been
finished.
finished
Then
then
we'll
we'll
inject
inject
element
element
ref
ref
in
in
the
the
constructor,
constructor
which
which
will
will
give
give
us
us
access
access
to
to
the
the
DOM
dom
element,
element
which
which
in
in
this
this
case
case
should
should
be
be
an
an
unordered
unordered
list.
list
So
so
once
once
that's
that's
done,
done
we
we
can
can
initialize
initialize
sortable
sortable
by
by
creating
creating
a
a
new
new
instance
instance
of
of
the
the
class
class
and
and
then
then
passing
passing
it
it
the
the
element
element
ref
ref
native
native
element.
element
Then
then
it
it
takes
takes
a
a
second
second
argument
argument
with
with
some
some
options.
options
We're
we're
going
going
to
to
specify
specify
the
the
draggable
draggable
elements
elements
as
as
the
the
list
list
items
items
within
within
that
that
list.
list
The
the
draggable
draggable
library
library
is
is
going
going
to
to
emit
emit
its
its
own
own
custom
custom
events
events
which
which
we
we
can
can
intercept
intercept
here
here
to
to
emit
emit
our
our
own
own
custom
custom
event
event
that
that
will
will
have
have
the
the
newly
newly
sorted
sorted
list.
list
Again,
again
there
there
are
are
multiple
multiple
custom
custom
events
events
that
that
you
you
might
might
need,
need
but
but
the
the
one
one
that
that
we
we
care
care
about
about
is
is
sortable
sortable
stop.
stop
At
at
that
that
point,
point
we
we
know
know
the
the
user
user
is
is
done
done
sorting
sorting
the
the
list.
list
So
so
we'll
we'll
go
go
ahead
ahead
and
and
take
take
the
the
initial
initial
array,
array
reorder
reorder
it,
it
and
and
then
then
emit
emit
that
that
out
out
through
through
our
our
custom
custom
event
event
emitter
emitter
so
so
the
the
parent
parent
component
component
can
can
listen
listen
to
to
it
it
and
and
handle
handle
it
it
accordingly.
accordingly
The
the
sortable
sortable
stop
stop
event
event
keeps
keeps
track
track
of
of
all
all
the
the
elements
elements
in
in
the
the
list,
list
and
and
it
it
will
will
give
give
us
us
the
the
new
new
index
index
and
and
the
the
old
old
index
index
of
of
the
the
item
item
that
that
was
was
moved.
moved
So
so
we'll
we'll
use
use
this
this
method
method
as
as
just
just
a
a
context
context
for
for
mutating
mutating
the
the
original
original
data.
data
So
so
what
what
we
we
can
can
do
do
here
here
is
is
take
take
the
the
original
original
data
data
as
as
our
our
starting
starting
point,
point
then
then
we
we
can
can
splice
splice
off
off
the
the
old
old
index
index
and
and
then
then
resplice
resplice
it
it
back
back
into
into
the
the
new
new
index.
index
Once
once
we
we
have
have
the
the
array
array
in
in
the
the
format
format
that
that
we
we
want,
want
we
we
can
can
go
go
ahead
ahead
and
and
emit
emit
it
it
out
out
as
as
the
the
value
value
from
from
our
our
custom
custom
event.
event
In
in
the
the
next
next
step,
step
we'll
we'll
have
have
the
the
parent
parent
component
component
listen
listen
to
to
this
this
event
event
and
and
then
then
update
update
the
the
Firestore
firestore
database
database
with
with
the
the
new
new
value.
value
Now
now
that
that
we
we
have
have
our
our
directive
directive
finished,
finished
we'll
we'll
go
go
into
into
the
the
HTML
html
for
for
the
the
component.
component
We
we
can
can
just
just
insert
insert
it
it
into
into
an
an
unordered
unordered
list
list
and
and
that
that
will
will
give
give
us
us
access
access
to
to
both
both
its
its
input
input
properties
properties
as
as
well
well
as
as
its
its
output
output
properties.
properties
The
the
data
data
that
that
we
we
read
read
from
from
the
the
database
database
will
will
be
be
an
an
observable.
observable
So
so
I'm
i'm
doing
doing
an
an
n
n
g
g
f
f
statement
statement
here
here
with
with
the
the
document
document
and
and
setting
setting
that
that
document
document
as
as
a
a
template
template
variable.
variable
Then
then
we'll
we'll
pass
pass
that
that
to
to
the
the
data
data
input
input
on
on
the
the
directive.
directive
And
and
then
then
lastly,
lastly
we
we
will
will
listen
listen
to
to
our
our
custom
custom
stop
stop
event,
event
and
and
then
then
we'll
we'll
write
write
an
an
event
event
handler
handler
that
that
will
will
update
update
the
the
database
database
when
when
that
that
fires.
fires
Now
now
we
we
can
can
loop
loop
over
over
the
the
array
array
of
of
emojis
emojis
and
and
render
render
a
a
list
list
item
item
for
for
each
each
one.
one
Then
then
while
while
we're
we're
here
here
in
in
the
the
HTML,
html
I
i
wanna
wanna
add
add
a
a
couple
couple
of
of
extra
extra
things.
things
First,
first
I'll
i'll
add
add
another
another
button
button
here
here
that
that
the
the
user
user
can
can
click
click
to
to
remove
remove
an
an
item
item
from
from
an
an
array.
array
Then
then
I'll
i'll
move
move
outside
outside
of
of
our
our
loop
loop
and
and
add
add
an
an
additional
additional
method
method
that
that
we
we
can
can
use
use
to
to
add
add
an
an
additional
additional
emoji
emoji
to
to
the
the
array.
array
And
and
these
these
are
are
mostly
mostly
just
just
so
so
I
i
can
can
show
show
you
you
the
the
new
new
array
array
methods
methods
in
in
Firestore.
firestore
Now
now
we'll
we'll
go
go
into
into
our
our
component
component
typescript
typescript
and
and
finish
finish
this
this
feature
feature
out.
out
I
i
am
am
importing
importing
Angular
angular
Firestore
firestore
and
and
then
then
also
also
Firestore
firestore
directly
directly
from
from
the
the
Firebase
firebase
app
app
name
name
space.
space
We
we
can
can
inject
inject
AngularFirestore
angularfirestore
in
in
the
the
constructor,
constructor
and
and
then
then
we'll
we'll
set
set
up
up
one
one
variable
variable
for
for
our
our
document
document
reference
reference
so
so
we
we
can
can
make
make
updates
updates
on
on
it,
it
and
and
then
then
another
another
one
one
for
for
the
the
actual
actual
observable
observable
data.
data
Then
then
I'll
i'll
go
go
ahead
ahead
and
and
define
define
those
those
during
during
n
n
g
g
on
on
init.
init
For
for
now,
now
I'm
i'm
just
just
going
going
to
to
point
point
to
to
a
a
dummy
dummy
document
document
that
that
I
i
have
have
saved
saved
in
in
the
the
emojis
emojis
collection.
collection
Then
then
we
we
can
can
define
define
our
our
observable
observable
of
of
that
that
document
document
by
by
calling
calling
value
value
changes
changes
on
on
the
the
reference.
reference
Here's
here's
what
what
that
that
document
document
actually
actually
looks
looks
like
like
in
in
the
the
database.
database
We
we
have
have
an
an
array
array
data
data
structure
structure
here
here
called
called
faves
faves
and
and
it
it
currently
currently
has
has
3
3
different
different
emojis
emojis
in
in
it.
it
When
when
the
the
user
user
sorts
sorts
this
this
list,
list
we
we
can
can
update
update
the
the
array
array
in
in
Firestore
firestore
by
by
simply
simply
making
making
a
a
reference
reference
to
to
the
the
document
document
and
and
calling
calling
update
update
with
with
the
the
new
new
array.
array
We
we
set
set
up
up
the
the
Event
event
Emitter
emitter
in
in
the
the
directive
directive
to
to
send
send
the
the
newly
newly
sorted
sorted
array.
array
So
so
this
this
is
is
all
all
the
the
code
code
we
we
need
need
to
to
update
update
the
the
document
document
in
in
Firestore.
firestore
But
but
if
if
you
you
want
want
to
to
add
add
a
a
single
single
item
item
to
to
the
the
array,
array
one
one
way
way
to
to
do
do
that
that
is
is
with
with
the
the
new
new
Firestore
firestore
array
array
union
union
method
method
which
which
will
will
ensure
ensure
that
that
a
a
unique
unique
item
item
is
is
added
added
to
to
the
the
existing
existing
array.
array
This
this
is
is
really
really
nice
nice
when
when
you
you
want
want
to
to
enforce
enforce
uniqueness
uniqueness
in
in
the
the
array
array
which
which
is
is
exactly
exactly
what
what
we
we
wanna
wanna
do
do
here.
here
So
so
we'll
we'll
call
call
Firestore
firestore
field
field
value
value
array
array
union
union
and
and
then
then
pass
pass
in
in
the
the
element
element
that
that
we
we
want
want
to
to
add
add
to
to
it.
it
If
if
that
that
value
value
already
already
exists
exists
in
in
the
the
array,
array
then
then
nothing
nothing
will
will
happen.
happen
But
but
otherwise,
otherwise
it
it
will
will
append
append
that
that
item
item
to
to
the
the
end
end
of
of
the
the
array.
array
You
you
can
can
also
also
remove
remove
items
items
from
from
the
the
array,
array
which
which
is
is
also
also
very
very
useful
useful
because
because
a
a
lot
lot
of
of
times
times
you
you
don't
don't
already
already
know
know
the
the
index
index
of
of
the
the
item
item
and
and
you
you
just
just
want
want
it
it
gone.
gone
So
so
Firestore
firestore
field
field
value
value
array
array
remove
remove
will
will
find
find
that
that
element
element
in
in
the
the
array
array
and
and
remove
remove
it.
it
So
so
that
that
takes
takes
care
care
of
of
all
all
of
of
our
our
typescript
typescript
code,
code
but
but
in
in
order
order
to
to
make
make
drag
drag
and
and
drop
drop
look
look
good,
good
you're
you're
going
going
to
to
have
have
to
to
spend
spend
quite
quite
a
a
bit
bit
of
of
time
time
in
in
your
your
CSS
css
styling.
styling
One
one
of
of
the
the
cool
cool
things
things
about
about
draggable
draggable
is
is
that
that
it
it
will
will
add
add
a
a
whole
whole
bunch
bunch
of
of
different
different
CSS
css
to
to
your
your
elements
elements
depending
depending
on
on
what
what
state
state
they're
they're
in
in
within
within
the
the
draggable
draggable
list.
list
For
for
example,
example
we
we
might
might
want
want
to
to
add
add
a
a
style
style
to
to
the
the
container
container
element
element
when
when
it's
it's
being
being
dragged
dragged
like
like
a
a
blue
blue
border.
border
Then
then
the
the
source
source
element
element
that's
that's
being
being
dragged,
dragged
we
we
might
might
wanna
wanna
make
make
that
that
a
a
lighter
lighter
color
color
and
and
scale
scale
it
it
down
down
a
a
little
little
bit.
bit
Then
then
once
once
the
the
item
item
is
is
placed,
placed
we'll
we'll
go
go
ahead
ahead
and
and
color
color
the
the
background
background
to
to
green
green
and
and
draggable
draggable
will
will
remove
remove
this
this
class
class
after
after
a
a
second
second
so
so
we
we
can
can
get
get
that
that
green
green
flashing
flashing
effect
effect
when
when
the
the
item
item
is
is
set.
set
And
and
another
another
cool
cool
thing
thing
draggable
draggable
does
does
is
is
that
that
it
it
creates
creates
a
a
mirror
mirror
element
element
item
item
is
is
set,
set
and
and
another
another
cool
cool
thing
thing
draggable
draggable
does
does
is
is
that
that
it
it
creates
creates
a
a
mirror
mirror
element
element
of
of
the
the
item
item
that
that
was
was
selected.
selected
So
so
you
you
can
can
use
use
that
that
to
to
build
build
out
out
a
a
more
more
complex
complex
and
and
to
to
handle
handle
things
things
like
like
animations.
animations
When
when
we
we
go
go
to
to
our
our
demo
demo
you
you
can
can
see
see
that
that
a
a
lot
lot
of
of
different
different
classes
classes
are
are
being
being
swapped
swapped
out
out
on
on
the
the
elements
elements
as
as
we
we
drag
drag
things
things
around
around
here.
here
And
and
as
as
you
you
can
can
imagine
imagine
doing
doing
this
this
kind
kind
of
of
stuff
stuff
reliably
reliably
from
from
scratch
scratch
takes
takes
a
a
lot
lot
of
of
time
time
and
and
effort,
effort
so
so
using
using
a
a
library
library
like
like
draggable
draggable
is
is
just
just
going
going
to
to
make
make
your
your
life
life
a
a
lot
lot
easier.
easier
I'm
i'm
gonna
gonna
go
go
ahead
ahead
and
and
wrap
wrap
up
up
the
the
video
video
there.
there
If
if
it
it
helped
helped
you,
you
please
please
like
like
and
and
subscribe.
subscribe
And
and
if
if
you
you
want
want
to
to
take
take
your
your
development
development
to
to
the
the
next
next
level,
level
consider
consider
becoming
becoming
a
a
pro
pro
member
member
at
at
angularfirebase.com.
angularfirebase.com
You'll
you'll
you'll
you'll
get
get
access
access
to
to
all
all
kinds
kinds
of
of
advanced
advanced
exclusive
exclusive
content
content
designed
designed
to
to
help
help
you
you
build
build
and
and
ship
ship
your
your
app
app
faster.
faster
Thanks
thanks
for
for
watching,
watching
and
and
I'll
i'll
talk
talk
to
to
you
you
soon.
soon
success
The speakers discuss the challenges of building a web application with a drag and drop sortable list, including the complexities of attaching items and the use of a file library called dragLot. They also explain the process of creating a sortable list and import events from Angular core. The speakers then go into detail about creating a Sortable code and updating a document in Firwork, including a new method to add a dummy document and a new method to add a mirror element item. They also promote a pro member page for developers to take their development to the next level.
Draggable Sortable Firestore
One of the more challenging features to build in a web application is a drag and drop sortable list, and it's even more challenging if you need to persist the data in a back end database. Instead of trying to reinvent the wheel, we're going to use a library called draggable that's maintained by Shopify. It's relatively lightweight and we can wrap it in Angular to make drag and drop features, much more enjoyable to code. If you're new to the channel, like and subscribe, and you can find the source code on angular firebase.com. What we're building today is a sortable list of emojis, the user can add or remove items from the list and they can drag items to change the order and have that order be saved in the database. This is a pretty complex thing to do from scratch because if you notice when we drag an item, it creates a mirror of the original element and toggles a whole bunch of CSS classes on the container and the individual items themselves. Draggable will make this feature surprisingly easy, but also give us enough flexibility to build something unique. In addition, Firestore recently released a couple of new helper methods that make it easy to add or remove elements from an array. So We'll take a look at those as well, but the first thing you need to get started is an Angular app with AngularFire installed. From there, we'll go to the command line and install draggable with npm. There are 2 main elements to this demo. 1st, we have a smart component, which is our emoji component, and it handles retrieving items from the database and can also add or remove new emojis to the list. Then we have a directive called sortable, which I'm going to call our dumb component because a directive is essentially just a component that doesn't have a custom HTML template. It can do pretty much everything a component can do, but instead it attaches itself to a host element and extends the functionality of that element. When working with sortable list like this, you'll usually attach this to an unordered list and then have your list items be sortable within it. We'll start by building out the directive and you'll notice that we're importing a bunch of things here from Angular core. And this is also where we'll import sortable from Shopify draggable. We're going to implement the AfterView init lifecycle hook on this directive just so we know that all of the children elements are available once we start running the sortable code on it. Then we're going to have it emit a custom event that has the new order of the sorted items. In order to be able to do that, we first need to pass in the initial items, which we'll do with an input property on the directive. Then after the items have been sorted, we'll emit our own custom event by using the output decorator and an event emitter. There's quite a few different events you can track here. So I've commented those out in case you need them. The only one we need is when the actual sorting has been finished. Then we'll inject element ref in the constructor, which will give us access to the DOM element, which in this case should be an unordered list. So once that's done, we can initialize sortable by creating a new instance of the class and then passing it the element ref native element. Then it takes a second argument with some options. We're going to specify the draggable elements as the list items within that list. The draggable library is going to emit its own custom events which we can intercept here to emit our own custom event that will have the newly sorted list. Again, there are multiple custom events that you might need, but the one that we care about is sortable stop. At that point, we know the user is done sorting the list. So we'll go ahead and take the initial array, reorder it, and then emit that out through our custom event emitter so the parent component can listen to it and handle it accordingly. The sortable stop event keeps track of all the elements in the list, and it will give us the new index and the old index of the item that was moved. So we'll use this method as just a context for mutating the original data. So what we can do here is take the original data as our starting point, then we can splice off the old index and then resplice it back into the new index. Once we have the array in the format that we want, we can go ahead and emit it out as the value from our custom event. In the next step, we'll have the parent component listen to this event and then update the Firestore database with the new value. Now that we have our directive finished, we'll go into the HTML for the component. We can just insert it into an unordered list and that will give us access to both its input properties as well as its output properties. The data that we read from the database will be an observable. So I'm doing an n g f statement here with the document and setting that document as a template variable. Then we'll pass that to the data input on the directive. And then lastly, we will listen to our custom stop event, and then we'll write an event handler that will update the database when that fires. Now we can loop over the array of emojis and render a list item for each one. Then while we're here in the HTML, I wanna add a couple of extra things. First, I'll add another button here that the user can click to remove an item from an array. Then I'll move outside of our loop and add an additional method that we can use to add an additional emoji to the array. And these are mostly just so I can show you the new array methods in Firestore. Now we'll go into our component typescript and finish this feature out. I am importing Angular Firestore and then also Firestore directly from the Firebase app name space. We can inject AngularFirestore in the constructor, and then we'll set up one variable for our document reference so we can make updates on it, and then another one for the actual observable data. Then I'll go ahead and define those during n g on init. For now, I'm just going to point to a dummy document that I have saved in the emojis collection. Then we can define our observable of that document by calling value changes on the reference. Here's what that document actually looks like in the database. We have an array data structure here called faves and it currently has 3 different emojis in it. When the user sorts this list, we can update the array in Firestore by simply making a reference to the document and calling update with the new array. We set up the Event Emitter in the directive to send the newly sorted array. So this is all the code we need to update the document in Firestore. But if you want to add a single item to the array, one way to do that is with the new Firestore array union method which will ensure that a unique item is added to the existing array. This is really nice when you want to enforce uniqueness in the array which is exactly what we wanna do here. So we'll call Firestore field value array union and then pass in the element that we want to add to it. If that value already exists in the array, then nothing will happen. But otherwise, it will append that item to the end of the array. You can also remove items from the array, which is also very useful because a lot of times you don't already know the index of the item and you just want it gone. So Firestore field value array remove will find that element in the array and remove it. So that takes care of all of our typescript code, but in order to make drag and drop look good, you're going to have to spend quite a bit of time in your CSS styling. One of the cool things about draggable is that it will add a whole bunch of different CSS to your elements depending on what state they're in within the draggable list. For example, we might want to add a style to the container element when it's being dragged like a blue border. Then the source element that's being dragged, we might wanna make that a lighter color and scale it down a little bit. Then once the item is placed, we'll go ahead and color the background to green and draggable will remove this class after a second so we can get that green flashing effect when the item is set. And another cool thing draggable does is that it creates a mirror element item is set, and another cool thing draggable does is that it creates a mirror element of the item that was selected. So you can use that to build out a more complex and to handle things like animations. When we go to our demo you can see that a lot of different classes are being swapped out on the elements as we drag things around here. And as you can imagine doing this kind of stuff reliably from scratch takes a lot of time and effort, so using a library like draggable is just going to make your life a lot easier. I'm gonna go ahead and wrap up the video there. If it helped you, please like and subscribe. And if you want to take your development to the next level, consider becoming a pro member at angularfirebase.com. You'll you'll get access to all kinds of advanced exclusive content designed to help you build and ship your app faster. Thanks for watching, and I'll talk to you soon.
The speakers discuss the challenges of building a web application with a drag and drop sortable list, including the complexities of attaching items and the use of a file library called dragLot. They also explain the process of creating a sortable list and import events from Angular core. The speakers then go into detail about creating a Sortable code and updating a document in Firwork, including a new method to add a dummy document and a new method to add a mirror element item. They also promote a pro member page for developers to take their development to the next level.

        [INST]
        You are youtuber called Fireship you make engaging high-intensity and entertaining coding tutorials and tech news. 
        you covers a wide range of topics relevant to programmers, aiming to help them learn and improve their skills quickly.
        
        Given the title of the video : Draggable Sortable Firestore 
        and a small summary : The speakers discuss the challenges of building a web application with a drag and drop sortable list, including the complexities of attaching items and the use of a file library called dragLot. They also explain the process of creating a sortable list and import events from Angular core. The speakers then go into detail about creating a Sortable code and updating a document in Firwork, including a new method to add a dummy document and a new method to add a mirror element item. They also promote a pro member page for developers to take their development to the next level.
        [/INST]
        
        Generate the video : One of the more challenging features to build in a web application is a drag and drop sortable list, and it's even more challenging if you need to persist the data in a back end database. Instead of trying to reinvent the wheel, we're going to use a library called draggable that's maintained by Shopify. It's relatively lightweight and we can wrap it in Angular to make drag and drop features, much more enjoyable to code. If you're new to the channel, like and subscribe, and you can find the source code on angular firebase.com. What we're building today is a sortable list of emojis, the user can add or remove items from the list and they can drag items to change the order and have that order be saved in the database. This is a pretty complex thing to do from scratch because if you notice when we drag an item, it creates a mirror of the original element and toggles a whole bunch of CSS classes on the container and the individual items themselves. Draggable will make this feature surprisingly easy, but also give us enough flexibility to build something unique. In addition, Firestore recently released a couple of new helper methods that make it easy to add or remove elements from an array. So We'll take a look at those as well, but the first thing you need to get started is an Angular app with AngularFire installed. From there, we'll go to the command line and install draggable with npm. There are 2 main elements to this demo. 1st, we have a smart component, which is our emoji component, and it handles retrieving items from the database and can also add or remove new emojis to the list. Then we have a directive called sortable, which I'm going to call our dumb component because a directive is essentially just a component that doesn't have a custom HTML template. It can do pretty much everything a component can do, but instead it attaches itself to a host element and extends the functionality of that element. When working with sortable list like this, you'll usually attach this to an unordered list and then have your list items be sortable within it. We'll start by building out the directive and you'll notice that we're importing a bunch of things here from Angular core. And this is also where we'll import sortable from Shopify draggable. We're going to implement the AfterView init lifecycle hook on this directive just so we know that all of the children elements are available once we start running the sortable code on it. Then we're going to have it emit a custom event that has the new order of the sorted items. In order to be able to do that, we first need to pass in the initial items, which we'll do with an input property on the directive. Then after the items have been sorted, we'll emit our own custom event by using the output decorator and an event emitter. There's quite a few different events you can track here. So I've commented those out in case you need them. The only one we need is when the actual sorting has been finished. Then we'll inject element ref in the constructor, which will give us access to the DOM element, which in this case should be an unordered list. So once that's done, we can initialize sortable by creating a new instance of the class and then passing it the element ref native element. Then it takes a second argument with some options. We're going to specify the draggable elements as the list items within that list. The draggable library is going to emit its own custom events which we can intercept here to emit our own custom event that will have the newly sorted list. Again, there are multiple custom events that you might need, but the one that we care about is sortable stop. At that point, we know the user is done sorting the list. So we'll go ahead and take the initial array, reorder it, and then emit that out through our custom event emitter so the parent component can listen to it and handle it accordingly. The sortable stop event keeps track of all the elements in the list, and it will give us the new index and the old index of the item that was moved. So we'll use this method as just a context for mutating the original data. So what we can do here is take the original data as our starting point, then we can splice off the old index and then resplice it back into the new index. Once we have the array in the format that we want, we can go ahead and emit it out as the value from our custom event. In the next step, we'll have the parent component listen to this event and then update the Firestore database with the new value. Now that we have our directive finished, we'll go into the HTML for the component. We can just insert it into an unordered list and that will give us access to both its input properties as well as its output properties. The data that we read from the database will be an observable. So I'm doing an n g f statement here with the document and setting that document as a template variable. Then we'll pass that to the data input on the directive. And then lastly, we will listen to our custom stop event, and then we'll write an event handler that will update the database when that fires. Now we can loop over the array of emojis and render a list item for each one. Then while we're here in the HTML, I wanna add a couple of extra things. First, I'll add another button here that the user can click to remove an item from an array. Then I'll move outside of our loop and add an additional method that we can use to add an additional emoji to the array. And these are mostly just so I can show you the new array methods in Firestore. Now we'll go into our component typescript and finish this feature out. I am importing Angular Firestore and then also Firestore directly from the Firebase app name space. We can inject AngularFirestore in the constructor, and then we'll set up one variable for our document reference so we can make updates on it, and then another one for the actual observable data. Then I'll go ahead and define those during n g on init. For now, I'm just going to point to a dummy document that I have saved in the emojis collection. Then we can define our observable of that document by calling value changes on the reference. Here's what that document actually looks like in the database. We have an array data structure here called faves and it currently has 3 different emojis in it. When the user sorts this list, we can update the array in Firestore by simply making a reference to the document and calling update with the new array. We set up the Event Emitter in the directive to send the newly sorted array. So this is all the code we need to update the document in Firestore. But if you want to add a single item to the array, one way to do that is with the new Firestore array union method which will ensure that a unique item is added to the existing array. This is really nice when you want to enforce uniqueness in the array which is exactly what we wanna do here. So we'll call Firestore field value array union and then pass in the element that we want to add to it. If that value already exists in the array, then nothing will happen. But otherwise, it will append that item to the end of the array. You can also remove items from the array, which is also very useful because a lot of times you don't already know the index of the item and you just want it gone. So Firestore field value array remove will find that element in the array and remove it. So that takes care of all of our typescript code, but in order to make drag and drop look good, you're going to have to spend quite a bit of time in your CSS styling. One of the cool things about draggable is that it will add a whole bunch of different CSS to your elements depending on what state they're in within the draggable list. For example, we might want to add a style to the container element when it's being dragged like a blue border. Then the source element that's being dragged, we might wanna make that a lighter color and scale it down a little bit. Then once the item is placed, we'll go ahead and color the background to green and draggable will remove this class after a second so we can get that green flashing effect when the item is set. And another cool thing draggable does is that it creates a mirror element item is set, and another cool thing draggable does is that it creates a mirror element of the item that was selected. So you can use that to build out a more complex and to handle things like animations. When we go to our demo you can see that a lot of different classes are being swapped out on the elements as we drag things around here. And as you can imagine doing this kind of stuff reliably from scratch takes a lot of time and effort, so using a library like draggable is just going to make your life a lot easier. I'm gonna go ahead and wrap up the video there. If it helped you, please like and subscribe. And if you want to take your development to the next level, consider becoming a pro member at angularfirebase.com. You'll you'll get access to all kinds of advanced exclusive content designed to help you build and ship your app faster. Thanks for watching, and I'll talk to you soon.
        