Coding

Intermediate React and Firebase Tutorial – Build an Evernote Clone

  • 00:00:00 alright guys so in this tutorial series
  • 00:00:01 we're going to be creating an Evernote
  • 00:00:03 clone and it's going to be almost a
  • 00:00:06 fully functional Evernote clone there's
  • 00:00:07 going to be certain features that were
  • 00:00:09 not going to be implementing in this
  • 00:00:10 tutorial such as users although I do
  • 00:00:12 have another video previous video that I
  • 00:00:14 created where we do go over that so if
  • 00:00:16 you'd like to learn more about that
  • 00:00:18 there is a link in the description below
  • 00:00:19 for that video series but in this video
  • 00:00:22 we're just going to focus on Evernote
  • 00:00:23 we're gonna be using firebase and we're
  • 00:00:25 going to be using a library called a
  • 00:00:27 react quill so I think it's time for us
  • 00:00:30 to go ahead and demonstrate what it is
  • 00:00:32 we're going to be making in this app so
  • 00:00:34 I can come over here and click new note
  • 00:00:35 and enter a new title call it new note I
  • 00:00:38 submitted the note and as you can see it
  • 00:00:40 selects it automatically and over here
  • 00:00:42 on the right we have a text editor and
  • 00:00:44 we can edit the title I'll just call it
  • 00:00:46 like new Note 2 and then I can come down
  • 00:00:49 here you can see it updated live and I
  • 00:00:51 can go heading 1 this is a header and
  • 00:00:56 again you can see it updates live over
  • 00:00:58 here and so I can you know just this is
  • 00:01:02 some more text you know just a show that
  • 00:01:05 we can have different sized texts and
  • 00:01:06 everything great another note we'll just
  • 00:01:08 say test list and come in here and
  • 00:01:13 create a list you know 1 2 3 so you can
  • 00:01:21 see we can create lists so we can make
  • 00:01:22 text bold and it updates live over here
  • 00:01:26 and I can go through and select each
  • 00:01:28 note I can also delete my notes and it
  • 00:01:30 says are you sure you want to delete
  • 00:01:31 note – I'll click yes and it goes ahead
  • 00:01:33 and selects the previous one
  • 00:01:35 automatically for me and I'll delete
  • 00:01:36 this one as well and that is what we're
  • 00:01:38 gonna be making in this tutorial series
  • 00:01:39 so I'll come over to here to firebase
  • 00:01:42 you're gonna want to go to consult
  • 00:01:43 firebase google.com make sure you create
  • 00:01:46 a firebase account you can just go to
  • 00:01:47 firebase create an account and once you
  • 00:01:49 have the account go to consult firebase
  • 00:01:51 google.com and you'll be presented with
  • 00:01:53 this go ahead and click Add project and
  • 00:01:56 inside of here we'll just call it
  • 00:01:57 Evernote clone and make sure you check
  • 00:02:00 this box and this box and click create
  • 00:02:02 project once that finishes go ahead and
  • 00:02:06 click continue and you'll see this
  • 00:02:09 dashboard screen over here on the left
  • 00:02:11 click database now
  • 00:02:13 firebase has two different types of
  • 00:02:15 databases they have cloud fire store and
  • 00:02:17 the real time database real time
  • 00:02:19 database is their older original
  • 00:02:20 database and fire store is their newer
  • 00:02:22 database so that's what we're going to
  • 00:02:24 be using when you click create database
  • 00:02:26 just make sure you click it under cloud
  • 00:02:29 fire store and not real time database so
  • 00:02:31 let's go ahead and click create database
  • 00:02:33 go ahead and start it in the test mode
  • 00:02:36 click Next
  • 00:02:37 go ahead and click the select the
  • 00:02:40 location nearest you and then done and
  • 00:02:43 then wait for that to finish once that
  • 00:02:45 finishes you'll be brought to this
  • 00:02:47 screen right here this is going to be
  • 00:02:49 basically a data table that shows a
  • 00:02:51 visual representation of your data
  • 00:02:53 inside of the database now if I click
  • 00:02:56 this rules area here you can see that
  • 00:02:58 it's very similar to JavaScript it's a
  • 00:03:00 little different but it's got similar
  • 00:03:02 syntax and you can see here it says
  • 00:03:03 allow read write and what that's saying
  • 00:03:06 is you can both read and write from this
  • 00:03:09 no matter what if you're not
  • 00:03:10 authenticated that it doesn't matter who
  • 00:03:12 you are or any of that you can read and
  • 00:03:15 write to this database so in a
  • 00:03:17 production environment you're not going
  • 00:03:18 to want to have this you're gonna want
  • 00:03:19 to have very strict access rules and
  • 00:03:21 you're going to want to set up
  • 00:03:22 authentication for your app but we're
  • 00:03:24 not going to be doing any of this in
  • 00:03:25 this tutorial I do have a video where I
  • 00:03:28 do go over autant ocation creating login
  • 00:03:30 forms and signup forms all through
  • 00:03:32 firebase I will include a link in the
  • 00:03:34 description for you to watch that
  • 00:03:36 tutorial series which includes those
  • 00:03:38 topics but we're not going to go over
  • 00:03:39 that in this particular video so just
  • 00:03:43 keep that in mind and so when we use and
  • 00:03:45 we setup our firebase within the app
  • 00:03:47 itself we're going to be exposing our
  • 00:03:49 API key so if anybody were to get a hold
  • 00:03:51 of that they could just use your your
  • 00:03:54 firebase so what I do is I delete my key
  • 00:03:59 once I'm done with the tutorial series
  • 00:04:01 or just don't show anybody your API key
  • 00:04:04 either to either of those you'll be fine
  • 00:04:07 just make sure you don't give away your
  • 00:04:09 API key to anybody so now that that is
  • 00:04:13 now that that's been said we can go to
  • 00:04:15 project overview here and then you go
  • 00:04:19 ahead and click this this little icon
  • 00:04:22 right here that looks like to HTML
  • 00:04:25 brackets
  • 00:04:25 when you click that just name this
  • 00:04:29 Evernote tutorial leave this unchecked
  • 00:04:32 and click register app and then once
  • 00:04:37 that finishes go ahead and I want you to
  • 00:04:40 copy this object right here don't
  • 00:04:42 include the script tags just copy what's
  • 00:04:45 inside of here and actually you don't
  • 00:04:47 have to copy right now we'll just keep
  • 00:04:50 this in mind keep this window open keep
  • 00:04:51 this right here and we'll get back to
  • 00:04:53 this shortly let's go ahead and install
  • 00:04:54 all of our dependencies for the project
  • 00:04:56 first and then we'll paste this into our
  • 00:04:58 application so we will be using create
  • 00:05:01 react app in order to initialize the
  • 00:05:03 react application project so go ahead
  • 00:05:07 and go to this link I will include it in
  • 00:05:09 the description so once you get to this
  • 00:05:12 link you'll see instructions on how to
  • 00:05:13 install create rack react app it's
  • 00:05:15 extremely simple and it is a facebook
  • 00:05:18 tutorial on how to do it it's very very
  • 00:05:20 short very very simple go ahead and
  • 00:05:22 install that and once you do have that
  • 00:05:24 installed open up your terminal window
  • 00:05:26 I'm gonna be using windows you can use
  • 00:05:27 any terminal window from either Linux
  • 00:05:30 Mac or Windows to follow along but let
  • 00:05:33 me increase the font size of this really
  • 00:05:35 quick so you can see all of this okay
  • 00:05:37 that should be quite a bit better for
  • 00:05:38 you so go ahead and navigate to wherever
  • 00:05:41 you want your project to be so I'm gonna
  • 00:05:43 be inside of my Documents folder or
  • 00:05:45 actually Dropbox so go ahead and just
  • 00:05:48 navigate to wherever you want your
  • 00:05:49 project to be and I'm gonna say create
  • 00:05:50 react app just like that and then you're
  • 00:05:54 gonna want to put the name of the app so
  • 00:05:55 I'm gonna say evernote evernote tutorial
  • 00:05:59 and then when you click enter it's going
  • 00:06:01 to actually go ahead and install this
  • 00:06:04 this project directory tree that's
  • 00:06:10 basically ready for you to get started
  • 00:06:12 on react so let's go ahead and wait for
  • 00:06:14 this to finish okay so once that
  • 00:06:16 finishes we're gonna want to go ahead
  • 00:06:17 and install our first dependency we're
  • 00:06:19 going to be using material UI for this
  • 00:06:21 which is going to be a library that
  • 00:06:24 allows us to make styling very easy it's
  • 00:06:27 going to handle a lot of things it just
  • 00:06:28 includes react components that we can
  • 00:06:30 use that makes things look pretty by
  • 00:06:32 default essentially so that we can focus
  • 00:06:34 solely on react and not have to worry
  • 00:06:36 about writing a ton of CSS
  • 00:06:38 so let's go ahead and start we're gonna
  • 00:06:41 say npm install at material – UI the
  • 00:06:47 slash core so go ahead and install that
  • 00:06:49 and once that's done go ahead and do NPM
  • 00:06:54 install at material – UI / icons and
  • 00:06:59 this is gonna give us a ton of icons to
  • 00:07:01 be able to use which I think we're only
  • 00:07:02 gonna be using two icons the trashcan
  • 00:07:04 for delete and the pencil and paper for
  • 00:07:07 edit so go ahead and wait for that to
  • 00:07:08 finish okay
  • 00:07:10 and for our text editor we'll be using a
  • 00:07:12 react quill which is an open source
  • 00:07:14 library so we will say npm install react
  • 00:07:17 – quill q UI ll go ahead and install
  • 00:07:22 that and finally we're gonna go ahead
  • 00:07:25 and install firebase so npm npm install
  • 00:07:29 firebase so let that finish really quick
  • 00:07:33 alright so that's gonna be all of our
  • 00:07:35 dependencies here so i'm gonna go ahead
  • 00:07:36 and clear my console and actually just
  • 00:07:38 type in npm space start to go ahead and
  • 00:07:42 get react up and running just to make
  • 00:07:43 sure everything is running smoothly so
  • 00:07:46 once this pops up i'll also go ahead and
  • 00:07:49 open up my console just to see if we
  • 00:07:50 have any errors and we do not so it
  • 00:07:52 looks like everything installed properly
  • 00:07:54 so over here go ahead and let's make
  • 00:07:59 sure we have this this stuff copied here
  • 00:08:02 and now that we have our firebase config
  • 00:08:05 copied let's go ahead and put it inside
  • 00:08:07 of our app just to get that part knocked
  • 00:08:09 out so we don't have to worry about it
  • 00:08:10 in just a moment so I've got my
  • 00:08:13 directory opened up now and I'll go into
  • 00:08:14 my source folder here and you want to
  • 00:08:16 open your index j s5 so we're going to
  • 00:08:19 want to do a quick require so we're
  • 00:08:20 gonna say Const firebase is equal to
  • 00:08:24 require and then inside of here we want
  • 00:08:26 to put inside of quotes firebase so a
  • 00:08:29 requiring firebase and then underneath
  • 00:08:31 this we want to just go ahead and say
  • 00:08:33 require and then in quotes firebase
  • 00:08:36 slash fire store oops there we go cool
  • 00:08:41 so under this you remember we copied
  • 00:08:43 that stuff from firebase so make sure
  • 00:08:46 you have that copied and let's go ahead
  • 00:08:47 and paste that here now I'm going to
  • 00:08:50 change varta Const
  • 00:08:52 and I'm gonna get rid of these two
  • 00:08:54 comments right here alright and what I
  • 00:08:57 like to do just to make it it might not
  • 00:09:00 actually be cleaner but this is the way
  • 00:09:02 I like to do I like to get rid of this
  • 00:09:03 variable here just get rid of the
  • 00:09:05 variable and then just take the actual
  • 00:09:07 object itself and paste it in between
  • 00:09:11 the parentheses there that's just how I
  • 00:09:13 like to do it but you can do it either
  • 00:09:15 way so now we have firebase initialized
  • 00:09:18 inside of our application I'm saving it
  • 00:09:20 right now and I'm coming over to the
  • 00:09:23 react app just to make sure I don't have
  • 00:09:24 any errors and it says here it looks
  • 00:09:27 like you're using the development build
  • 00:09:29 a firebase jeaious SDK now this is
  • 00:09:32 perfectly fine this is saying we're
  • 00:09:33 using the development build which is
  • 00:09:35 fine because we are in development now
  • 00:09:37 you we're gonna be getting this message
  • 00:09:38 throughout the entire tutorial so we can
  • 00:09:41 safely ignore this particular message so
  • 00:09:44 as you see it here in the console as we
  • 00:09:45 work through the tutorial just ignore
  • 00:09:48 this it's fine alright moving on so the
  • 00:09:51 first thing I like to do is I like to
  • 00:09:53 come in here and delete all this default
  • 00:09:55 stuff that comes with the default react
  • 00:09:58 app so I go into a pas here and inside
  • 00:10:02 of this return I'm actually I'm gonna
  • 00:10:05 get rid of this whole thing and make it
  • 00:10:06 a class so I'll come in here and say
  • 00:10:07 class app extends react component and
  • 00:10:14 now we have a class instead of a
  • 00:10:16 function which the class needs to
  • 00:10:18 actually needs to implement the render
  • 00:10:22 function and inside of the render
  • 00:10:25 function you have to return some HTML so
  • 00:10:28 for now I'll put in a div that just says
  • 00:10:30 hello world cool so I'll save that and
  • 00:10:34 let's see what we end up with really
  • 00:10:36 quick we have hello world here cool so
  • 00:10:39 as most of you probably know the way
  • 00:10:41 that this works is inside of the
  • 00:10:42 index.js file we have this app element
  • 00:10:45 which is represented by this app class
  • 00:10:47 here because we were importing it right
  • 00:10:50 here and what this is doing is react Dom
  • 00:10:52 rendered takes whatever's inside of here
  • 00:10:55 does some react magic to turn it into
  • 00:10:59 actual code that basically we write it
  • 00:11:03 in a react way and then it takes that
  • 00:11:05 react way and turns into actual code
  • 00:11:08 that the browser understands and then it
  • 00:11:10 pushes it into document dot get element
  • 00:11:13 by ID root and if I come in here you can
  • 00:11:16 see if I go to elements do expand this
  • 00:11:20 get rid of this if I go inside a body
  • 00:11:23 here you can see there's this div here
  • 00:11:24 with an ID of root and everything inside
  • 00:11:27 of the react application is going to get
  • 00:11:30 injected inside of this div called root
  • 00:11:32 so you don't actually have to you know I
  • 00:11:36 really want you guys to understand react
  • 00:11:38 so let's go into the public here and
  • 00:11:41 inside the index.html you can see that
  • 00:11:45 that div is actually right here with
  • 00:11:47 root so what I want to do just to kind
  • 00:11:49 of show you and get you really
  • 00:11:50 comfortable with this sort of idea is
  • 00:11:51 instead of call it root I'm gonna call
  • 00:11:53 it
  • 00:11:54 Evernote container so go ahead and call
  • 00:11:58 this Evernote container and I want you
  • 00:12:00 to save it and I want you to take that
  • 00:12:02 copy it and paste it inside of here so
  • 00:12:08 now we're injecting it inside of a div
  • 00:12:09 called Evernote container instead of ruh
  • 00:12:11 and I want you to save both of those
  • 00:12:13 files and come back in here and notice
  • 00:12:14 that it works still and if you come back
  • 00:12:16 over here you can see that that div has
  • 00:12:18 an ID of Evernote container so that's
  • 00:12:20 just to kind of get you a little bit
  • 00:12:22 comfortable with how react is working
  • 00:12:24 and that it's not entirely magic you can
  • 00:12:26 actually come in here and change some of
  • 00:12:29 these things it's not mandatory and you
  • 00:12:31 can actually extend it too this is all
  • 00:12:33 open source you don't have to be afraid
  • 00:12:36 of react alright there's actually one
  • 00:12:38 more thing we need to add so inside of
  • 00:12:39 the source folder create a new file call
  • 00:12:42 that helpers dot J S and inside of here
  • 00:12:44 we're gonna paste some stuff go to the
  • 00:12:46 source code the source code is going to
  • 00:12:48 be linked in the description of this
  • 00:12:49 video go ahead and go to that source
  • 00:12:51 code find at the helpers J's file and
  • 00:12:53 paste this in so what this is going to
  • 00:12:56 be we have a debounce function which is
  • 00:12:59 going to be helpful for us because what
  • 00:13:01 when we are typing inside of the text
  • 00:13:04 editor we're going to want to update the
  • 00:13:06 database live however we don't want to
  • 00:13:08 send
  • 00:13:09 we don't want to send requests every
  • 00:13:12 every single time we type a a letter
  • 00:13:15 we're gonna want to wait for the user to
  • 00:13:17 stop typing for about a second or so
  • 00:13:20 maybe two seconds before we update the
  • 00:13:23 database so that we're not just going
  • 00:13:24 crazy on the database with all these
  • 00:13:26 calls these HTTP calls so we're gonna be
  • 00:13:30 using a deep balance function right here
  • 00:13:31 and then we're also going to have this
  • 00:13:32 export function where you remove HTML
  • 00:13:35 tags that function is going to be for
  • 00:13:38 our preview on the Left sidebar whenever
  • 00:13:42 we see the list of notes we're going to
  • 00:13:45 we're going to remove the HTML for the
  • 00:13:48 preview and basically react quill the
  • 00:13:52 text editor library that we're using
  • 00:13:55 actually stores its it displays it as
  • 00:13:59 actual HTML so we're going to be saving
  • 00:14:01 HTML as a string to the database so when
  • 00:14:05 we display the preview in the sidebar we
  • 00:14:09 don't want to show the HTML tags that
  • 00:14:11 would just look weird so we have this
  • 00:14:13 function here that's going to be
  • 00:14:15 removing the HTML from that so we can
  • 00:14:18 just see the plain text previews so for
  • 00:14:20 the majority of the application we're
  • 00:14:24 going to be using something called width
  • 00:14:26 styles which is actually going to be
  • 00:14:28 from material UI instead of writing
  • 00:14:31 plain CSS but there is going to be a
  • 00:14:33 little of plain CSS for the app level
  • 00:14:36 project so go ahead and open up your app
  • 00:14:38 dot CSS and we want to go ahead and
  • 00:14:40 remove all this stuff this was just the
  • 00:14:42 default CSS that we saw when we first
  • 00:14:44 started up our react application with
  • 00:14:46 react create react app it had the big
  • 00:14:48 you know react logo and it was spinning
  • 00:14:51 around and doing cool stuff we don't
  • 00:14:52 need any of that so go ahead and remove
  • 00:14:54 all that go to the source code and in
  • 00:14:57 the source code you'll find app dot CSS
  • 00:14:59 go ahead copy all of that and paste it
  • 00:15:01 in here we don't want to worry about CSS
  • 00:15:03 in this tutorial so we're going to be
  • 00:15:04 copying all of our Styles from the
  • 00:15:07 source code and pasting that stuff in so
  • 00:15:08 go ahead and save your app dot CSS file
  • 00:15:11 cool so we're ready to go ahead and get
  • 00:15:14 started so let's go ahead and remove
  • 00:15:15 this import logo from the SVG here we're
  • 00:15:19 not gonna be using that that's just the
  • 00:15:20 react logo that's included with the
  • 00:15:21 project
  • 00:15:22 so what we want to do is start with a
  • 00:15:24 constructor and inside of this
  • 00:15:26 constructor we have to go ahead and
  • 00:15:27 implement the super and then what we'll
  • 00:15:31 do is create some initial State so we'll
  • 00:15:33 say this state is equal to and inside of
  • 00:15:36 this object we're going to have three
  • 00:15:38 slices of state one is going to be
  • 00:15:40 called selected note index and that will
  • 00:15:43 be set to null by default these will all
  • 00:15:46 be Nold by default so select it note as
  • 00:15:49 well that'll be null and then notes
  • 00:15:52 which will be the array of all of the
  • 00:15:54 notes that we have and that will also be
  • 00:15:56 null so now that we have our initial
  • 00:15:59 state what we want to do is underneath
  • 00:16:00 the render function we want to go ahead
  • 00:16:02 and implement the react hook called
  • 00:16:05 component didn't mount and what that is
  • 00:16:07 is whenever the this particular
  • 00:16:10 component the app component is loaded
  • 00:16:12 successfully inside of the Dom this will
  • 00:16:15 get called automatically by reacted as a
  • 00:16:17 life cycle hook that is built-in to
  • 00:16:18 react so let's go ahead and implement
  • 00:16:20 component did mount and we want to go
  • 00:16:26 ahead and go into firebase grab all of
  • 00:16:30 the notes and then set our state with
  • 00:16:32 the notes this little slice right here
  • 00:16:34 but in order to do that we actually have
  • 00:16:35 to come up here and import firebase
  • 00:16:37 really quick so underneath all of these
  • 00:16:39 imports let's go ahead and say Const
  • 00:16:41 firebase is equal to require and then
  • 00:16:47 firebase cool so now we have access to
  • 00:16:50 firebase so we want to say firebase and
  • 00:16:53 then that's gonna be dot fire store and
  • 00:16:56 I'm actually going to put these on
  • 00:16:57 individual lines so it's easier for you
  • 00:16:59 guys to see so dot fire store dot
  • 00:17:02 collection and what collection is is
  • 00:17:05 it's basically very similar to a table
  • 00:17:08 in a database our collection we're going
  • 00:17:11 to name notes so we'll go ahead and name
  • 00:17:13 that notes and I'll show you in just a
  • 00:17:15 moment what that looks like in that
  • 00:17:16 little table visualizer on firebase but
  • 00:17:19 for now just follow along so dot
  • 00:17:22 collection notes dot on snapshot now
  • 00:17:24 what on snapshot is this is actually
  • 00:17:26 very interesting this is very powerful
  • 00:17:27 on snapshot is going to automatically
  • 00:17:32 get called whenever this notes collide
  • 00:17:36 is updated inside a firebase so whenever
  • 00:17:38 something gets updated inside of the
  • 00:17:41 notes collection in firebase the
  • 00:17:42 function that we pass into on snapshot
  • 00:17:46 will get called and that specific
  • 00:17:48 function is going to be passed a an
  • 00:17:51 argument automatically that we're going
  • 00:17:53 to be calling server update so that's
  • 00:17:56 going to be the argument for the
  • 00:17:57 function that we're passing into this
  • 00:17:58 and let's go ahead and create a Const
  • 00:18:02 called notes which is going to be our
  • 00:18:04 array so we want to go ahead and set
  • 00:18:07 that equal to server update Docs and
  • 00:18:09 Doc's is a property of the server update
  • 00:18:12 parameter I'm sorry Docs is a property
  • 00:18:16 of the server update object that's
  • 00:18:18 getting passed into our function and we
  • 00:18:21 want to map it and so if you're not
  • 00:18:22 super familiar with the map function in
  • 00:18:25 JavaScript I've got a really good
  • 00:18:26 tutorial on that go ahead and look in
  • 00:18:28 the description and watch that tutorial
  • 00:18:30 it's very short
  • 00:18:31 but it's got a visual representation of
  • 00:18:33 how map works inside of JavaScript and
  • 00:18:35 if you're not very familiar familiar
  • 00:18:37 with that I highly recommend you watch
  • 00:18:39 that tutorial really quick because we're
  • 00:18:41 going to be using it a lot in this
  • 00:18:42 tutorial series so let's go ahead and
  • 00:18:45 say for each dock we want to create a
  • 00:18:49 Const called data and set it equal to
  • 00:18:51 doc data which is a function which grabs
  • 00:18:54 the data from the dock and we want to
  • 00:18:57 add a property to our data object that
  • 00:19:02 we're creating called ID so data ID will
  • 00:19:09 literally just be equal to doc dot ID
  • 00:19:13 and then we're going to return that so
  • 00:19:16 our return data so we successfully have
  • 00:19:19 an array of all of the notes and then we
  • 00:19:21 want to go ahead and update our state so
  • 00:19:23 this set state and inside of here we
  • 00:19:27 want to update the notes slice of our
  • 00:19:29 state with our notes that we just
  • 00:19:30 created right here so we're setting our
  • 00:19:33 notes state equal to this array that we
  • 00:19:35 we just mapped right here so we don't
  • 00:19:38 have anything inside of we don't have
  • 00:19:40 any notes so we can't really see what
  • 00:19:42 this looks like yet but what I want to
  • 00:19:43 do is go ahead and create a console dot
  • 00:19:45 log statement console dot log
  • 00:19:48 notes and I want to save it because I
  • 00:19:50 want to show you guys what this looks
  • 00:19:52 like so as you can see we come here and
  • 00:19:55 when I go to the console we have an
  • 00:19:56 empty array and that's simply because we
  • 00:19:58 don't have any notes inside a firebase
  • 00:20:00 so let's go up here to firebase and I
  • 00:20:02 want you to go back to your database and
  • 00:20:04 you can see this table here so when we
  • 00:20:07 add a collection remember we call that
  • 00:20:08 collection notes okay and we click Next
  • 00:20:11 and then for each note that's going to
  • 00:20:14 be a document and it'll have this auto
  • 00:20:16 ID and the dock the the notes are going
  • 00:20:21 to have two will actually three
  • 00:20:23 properties the first property is going
  • 00:20:25 to be a title and what is call it tests
  • 00:20:27 note from firebase it'll also have a a
  • 00:20:33 body so we'll call it body and then
  • 00:20:35 that's going to actually end up being a
  • 00:20:37 string of HTML so in here I'm just going
  • 00:20:39 to put an h1 tag hello world and at
  • 00:20:45 closing h1 tag and then it'll also have
  • 00:20:47 a timestamp but I'm not going to worry
  • 00:20:49 about the timestamp here in this
  • 00:20:51 particular case because we're going to
  • 00:20:52 automatically generate that timestamp so
  • 00:20:55 I'm gonna click Save and I can see that
  • 00:20:58 we have a note here and if you remember
  • 00:21:01 when I said whenever the notes
  • 00:21:03 collection is updated it's going to
  • 00:21:06 automatically call that on snapshot
  • 00:21:08 function that we're passing a function
  • 00:21:10 into so let's go back over here and as
  • 00:21:13 you can see it went ahead and actually
  • 00:21:16 ran that function automatically simply
  • 00:21:17 because I updated the notes the notes
  • 00:21:22 collection so you can see here now that
  • 00:21:25 we have a title ID and body of a single
  • 00:21:28 note that we just created inside a
  • 00:21:29 firebase so with that being said I'm
  • 00:21:34 gonna go ahead and keep this console dot
  • 00:21:35 log notes here just for reference and
  • 00:21:37 then let's move on so I'm gonna actually
  • 00:21:39 remove all of these tabs up here so I
  • 00:21:41 can keep everything clean and inside of
  • 00:21:43 the source folder I want to create I
  • 00:21:45 actually want to create three other
  • 00:21:47 folders so we'll call the first folder
  • 00:21:49 editor the second folder we will call
  • 00:21:54 sidebar
  • 00:21:56 and then the third folder will call
  • 00:21:58 sidebar item now let's go ahead and get
  • 00:22:02 rid of let's go ahead and knock this
  • 00:22:04 boilerplate stuff out so inside of
  • 00:22:06 editor create a new file called editor
  • 00:22:09 j/s and you're gonna want another file
  • 00:22:12 called Styles j/s and you're gonna want
  • 00:22:15 to do that for each of these so new file
  • 00:22:17 sidebar a s and a styles J s and then
  • 00:22:24 finally sidebar item J s and a Styles j
  • 00:22:30 s for that one as well so let's go
  • 00:22:32 inside of each of these and just create
  • 00:22:34 the classes and the imports that we're
  • 00:22:35 going to need for each of these so that
  • 00:22:38 we can start focusing on the
  • 00:22:39 functionality so start by going into
  • 00:22:41 your editor j s and i want you to find
  • 00:22:43 the editor j s file in the source code
  • 00:22:46 and i want you to copy and paste these
  • 00:22:48 imports here once you have those imports
  • 00:22:51 go ahead and come down here and type in
  • 00:22:53 class editor component that's what we're
  • 00:22:56 going to call this class it's going to
  • 00:22:59 extend react component and inside of
  • 00:23:03 here we'll have a constructor that calls
  • 00:23:06 super and then we have to go ahead and
  • 00:23:10 have the render function and whoops and
  • 00:23:16 the render function has to return some
  • 00:23:18 HTML so what I will do is inside of here
  • 00:23:21 I will just simply say hello from the
  • 00:23:23 editor and that's going to be our class
  • 00:23:28 our boilerplate code for our class and
  • 00:23:30 what we need to do at the very bottom
  • 00:23:32 here is actually export this but we're
  • 00:23:34 going to use with styles so I'm gonna
  • 00:23:35 explain how that works just give me a
  • 00:23:37 second let's go ahead and say export
  • 00:23:38 default with styles which you can see we
  • 00:23:43 are importing right here from material –
  • 00:23:45 UI / core / styles so export default
  • 00:23:49 with styles which takes a argument
  • 00:23:52 because it's a function and that is
  • 00:23:54 going to be styles now we're passing
  • 00:23:56 styles in – with styles with styles is
  • 00:24:01 actually going to return yet another
  • 00:24:02 function so we'll go ahead and
  • 00:24:04 immediately invoke that function that it
  • 00:24:06 returns with our editor
  • 00:24:07 component okay so what styles is is it's
  • 00:24:12 actually going to end up being a
  • 00:24:13 function that we're going to put inside
  • 00:24:15 of the styles J s file here you don't
  • 00:24:18 have to worry about that I'm actually
  • 00:24:19 gonna have you go ahead and copy that
  • 00:24:21 and paste it inside of here from the
  • 00:24:23 source code but I want you to understand
  • 00:24:25 how this is working so inside of here
  • 00:24:27 there's going to be a function that has
  • 00:24:30 a bunch of a bunch of classes that are
  • 00:24:33 going to be they're going to represent
  • 00:24:35 CSS styles here it's taking those styles
  • 00:24:39 and then basically creating an object
  • 00:24:42 called classes or a property and react
  • 00:24:45 it's actually props so it's creating a
  • 00:24:47 prop called classes and we're going to
  • 00:24:50 be able to access those classes from the
  • 00:24:52 it'll look like this it'll be classes
  • 00:24:55 well this dot props top oops this dot
  • 00:24:59 props dot classes dot class name so
  • 00:25:04 that's going to be really helpful for us
  • 00:25:05 shortly so go ahead and save this let's
  • 00:25:07 knock out the boilerplate code for the
  • 00:25:10 other two components so go ahead and go
  • 00:25:13 to your sidebar J's file and inside of
  • 00:25:18 here go ahead go to the source code copy
  • 00:25:20 the imports paste the imports inside of
  • 00:25:22 here and then class side bar sidebar
  • 00:25:26 component extends react component and
  • 00:25:33 again we'll want a constructor here that
  • 00:25:37 calls super and then under here I'll
  • 00:25:40 just copy from my previous file here the
  • 00:25:42 render function and then instead of
  • 00:25:47 Hello from editor we'll say hello from
  • 00:25:49 sidebar and then again we'll say export
  • 00:25:56 default with styles
  • 00:25:59 the first argument will be styles and
  • 00:26:02 the second one will be our sidebar
  • 00:26:04 component okay and let's knock out the
  • 00:26:08 final one so under sidebar item jeaious
  • 00:26:12 go ahead and go into the source code and
  • 00:26:15 copy the imports fourth paste the
  • 00:26:17 imports inside of here and then go to go
  • 00:26:20 ahead and type in class
  • 00:26:21 sidebar item component extends react dot
  • 00:26:26 component and of course it's going to
  • 00:26:30 have a constructor here with super and
  • 00:26:33 then the render function which I will
  • 00:26:36 again copy from the previous one and
  • 00:26:40 instead of sidebar will say sidebar item
  • 00:26:43 so now we have the boilerplate code
  • 00:26:45 actually I need to do the the exports of
  • 00:26:48 export default sidebar item component
  • 00:26:53 nope that's gonna be with styles styles
  • 00:26:56 is the first argument and then the
  • 00:26:59 sidebar item component all right so now
  • 00:27:02 we got all of that done so the second
  • 00:27:05 thing that we want to do is you want to
  • 00:27:06 go into the source code grab the Styles
  • 00:27:09 JS file for each of these three
  • 00:27:11 components and paste them in so I'm
  • 00:27:13 going to go ahead and do that right now
  • 00:27:14 you go ahead and do it as well so I'm
  • 00:27:17 gonna start with my Styles JS file for
  • 00:27:19 my editor so under under editor here
  • 00:27:24 inside of Styles jeaious I simply paste
  • 00:27:26 this and as you can see Styles is a
  • 00:27:30 function with a argument called theme
  • 00:27:33 that's passed into it automatically by
  • 00:27:34 material UI which returns an object of
  • 00:27:38 basically CSS classes and styles so go
  • 00:27:41 ahead and save that and then move on to
  • 00:27:44 the sidebar Styles j/s file go ahead and
  • 00:27:47 copy it from the source code paste that
  • 00:27:49 in and then do the same thing for the
  • 00:27:52 Styles j/s inside of the sidebar item
  • 00:27:56 and once you have all of that we have
  • 00:27:58 all of our boilerplate code so we can
  • 00:28:00 actually go ahead and get started on the
  • 00:28:01 fun stuff so inside of our app dot J's
  • 00:28:06 file I'm actually going to get rid of
  • 00:28:07 all these tabs inside of our app dot J's
  • 00:28:10 file inside of render I want to actually
  • 00:28:13 render out our new components so in
  • 00:28:18 react we can only return one component
  • 00:28:20 but we can have components inside of
  • 00:28:22 other components or we can let me
  • 00:28:24 rephrase that we can only return one
  • 00:28:28 element but we can have other elements
  • 00:28:29 or components inside of that element so
  • 00:28:31 we'll create one parent element
  • 00:28:34 and it'll be a div here and I'll just go
  • 00:28:36 ahead and give this a class name of
  • 00:28:39 let's say app container and then inside
  • 00:28:44 of here let's go ahead and put in our
  • 00:28:46 sidebar component which we are going to
  • 00:28:52 need to import so let's go ahead and
  • 00:28:54 import sidebar component from and that
  • 00:28:58 will be dot board slash sidebar slash
  • 00:29:01 sidebar might as well go ahead and do
  • 00:29:03 the same thing for the editor so import
  • 00:29:06 editor component from dock ford slash
  • 00:29:13 editor forward slash editor okay so we
  • 00:29:18 don't need to import the sidebar item
  • 00:29:19 component because the sidebar component
  • 00:29:21 is going to use the sorry sidebar item
  • 00:29:24 component so we don't have to use that
  • 00:29:25 inside of that j/s so we have that and
  • 00:29:28 let's go ahead and also put our editor
  • 00:29:29 component inside of here cool so let's
  • 00:29:34 save this and see what we end up with
  • 00:29:37 alright cool so a whole bunch of nothing
  • 00:29:41 it's still compiling on my end
  • 00:29:42 let me there we go cool so as you can
  • 00:29:45 see here we have hello from sidebar and
  • 00:29:48 hello from the editor we also have a few
  • 00:29:51 warning messages but we're not gonna
  • 00:29:53 worry about that that's just saying hey
  • 00:29:55 you have imported some stuff but you're
  • 00:29:57 not using it it says no unused bars
  • 00:29:59 that's because we went ahead and knocked
  • 00:30:00 out all those imports before you wrote
  • 00:30:02 the code so just don't worry about these
  • 00:30:04 warnings right now but as you can see
  • 00:30:06 they are importing and displaying the
  • 00:30:08 components as expected alright so what I
  • 00:30:12 want to do now is I want to go ahead and
  • 00:30:14 demonstrate the react quill you know
  • 00:30:16 what it comes with the features of it
  • 00:30:17 and how we're gonna be using it inside
  • 00:30:19 of this application but before we do
  • 00:30:20 that I need you to go to the source code
  • 00:30:22 so go to the description go to the
  • 00:30:24 source code go into the public folder
  • 00:30:26 and then the index.html file and then
  • 00:30:29 what you'll see in the source code at
  • 00:30:31 the top of inside of the header tags at
  • 00:30:35 the very top you'll see a link a link
  • 00:30:39 tag with I'll show you exactly what it
  • 00:30:41 looks like here so you it'll be right
  • 00:30:44 here
  • 00:30:45 and this is what this is is it's the
  • 00:30:47 styles for react quill it's the style
  • 00:30:50 phew so go ahead and paste that in
  • 00:30:52 exactly where you see it here save it
  • 00:30:54 and now we have access to the CSS that
  • 00:30:57 we're going to need for react quilt so
  • 00:31:00 now that we have that I'm gonna go ahead
  • 00:31:01 and move this window over here and
  • 00:31:03 actually bring it a little bit further
  • 00:31:04 over so you can see everything go ahead
  • 00:31:06 and have your editor J s file open and
  • 00:31:09 I'm gonna start moving this HTML onto
  • 00:31:13 its own lines just to make it look clean
  • 00:31:16 and I'm gonna get rid of hello from the
  • 00:31:19 editor okay so the first thing I want to
  • 00:31:22 do here is inside of this render
  • 00:31:24 function at the top I want to go ahead
  • 00:31:25 and D structure out the classes variable
  • 00:31:28 so I will do that now so Const classes
  • 00:31:33 equals this dot props so now I have
  • 00:31:38 access to that classes variable from
  • 00:31:40 this dot props and I'm going to go ahead
  • 00:31:42 and use that here so we're gonna give
  • 00:31:44 this parent div here a class name and
  • 00:31:47 the class name is going to be equal to
  • 00:31:48 classes editor container and now I want
  • 00:31:56 to go ahead and throw in this react
  • 00:31:58 quill element and save and let's see
  • 00:32:03 what we end up with over here so as you
  • 00:32:05 can see we have a text editor inside of
  • 00:32:10 here now
  • 00:32:11 it looks kind of wonky at this at this
  • 00:32:13 moment and that's just due to the styles
  • 00:32:14 because we're gonna have a little extra
  • 00:32:16 room for the sidebar but this sidebar
  • 00:32:18 will be over here and right now we have
  • 00:32:22 hello from the sidebar above is so it
  • 00:32:24 looks a little weird right now but
  • 00:32:26 that's perfectly fine we'll get to that
  • 00:32:28 in just a second but I just wanted to
  • 00:32:30 come in here and kind of show you what a
  • 00:32:32 react quill comes with right off the bat
  • 00:32:34 so as you can see here it comes with all
  • 00:32:37 of what you need in order to get started
  • 00:32:39 with a text editor now it also has some
  • 00:32:43 built-in functions so I'm just going in
  • 00:32:47 here and just kind of showing you that
  • 00:32:48 it has all this stuff built in alright
  • 00:32:50 cool so
  • 00:32:53 it comes with some functions that are
  • 00:32:55 going to be really helpful for us when
  • 00:32:57 trying to use this inside of our
  • 00:33:00 application so now that I've kind of
  • 00:33:03 demonstrated what that looks like I
  • 00:33:04 think it's time to go ahead and start
  • 00:33:06 implementing some of the functions now I
  • 00:33:09 want to go ahead and start implementing
  • 00:33:10 these functions while it does look kind
  • 00:33:12 of weird so we're gonna be using the
  • 00:33:14 console to do a lot of logging here so
  • 00:33:16 just go ahead and have your console open
  • 00:33:18 and let's go ahead and get started
  • 00:33:21 implementing these functions all right
  • 00:33:24 so the first property we're going to
  • 00:33:26 utilize from react quill is value so the
  • 00:33:30 value we will set equal to this state
  • 00:33:34 dot txt and you know we've got this
  • 00:33:36 state variable here so what we're gonna
  • 00:33:38 do is whatever the state whatever the
  • 00:33:41 text state is it's going to be the value
  • 00:33:44 property of react quill so as we update
  • 00:33:47 this state it's going to update the
  • 00:33:49 react quill value property the second
  • 00:33:53 thing that we're gonna throw in here is
  • 00:33:54 on change and we're gonna have a
  • 00:33:58 function called this update body so I'm
  • 00:34:02 gonna put this stuff on its own line
  • 00:34:04 really quick just make it look clean so
  • 00:34:11 we have value and on change now this to
  • 00:34:15 update body is going to be a function
  • 00:34:18 that is going to be asynchronous that's
  • 00:34:21 going to set some state and once the
  • 00:34:24 state updates we're going to call an
  • 00:34:25 update function that is going to do some
  • 00:34:30 stuff I don't want to talk too far ahead
  • 00:34:31 so let's go ahead and implement update
  • 00:34:33 body so I'm gonna put up day body
  • 00:34:36 directly under my return sorry under my
  • 00:34:39 render so I'll go to my render function
  • 00:34:42 and create a variable called update body
  • 00:34:44 which I'll set to a function now this is
  • 00:34:47 going to be an asynchronous function so
  • 00:34:48 go ahead and add your async keyword and
  • 00:34:50 it's going to accept a value and we're
  • 00:34:53 gonna do stuff with that value so like I
  • 00:34:56 said we're going to set some state but
  • 00:34:58 we're gonna wait for that state to
  • 00:34:59 update so we're gonna say oh wait this
  • 00:35:02 outset state
  • 00:35:04 and the chunk of state that we want to
  • 00:35:07 update is going to be text and we're
  • 00:35:09 gonna update it with Val and once that
  • 00:35:13 state is updated we're gonna call this
  • 00:35:15 update which we do not have yet so
  • 00:35:20 underneath update body we will create a
  • 00:35:22 function called update now this is where
  • 00:35:25 things get a little somewhat complicated
  • 00:35:28 so I'm gonna do my best to explain it
  • 00:35:30 for you so we have a function called
  • 00:35:33 update and we're gonna set it equal to D
  • 00:35:36 bounce and we're gonna pass a function
  • 00:35:40 into D bounce which is going to be the
  • 00:35:41 actual function so I'll explain this in
  • 00:35:45 just a second I just want to get this
  • 00:35:46 out of the way okay
  • 00:35:48 so D bounces and our helpers so if I go
  • 00:35:51 to helpers J s we imported we imported
  • 00:35:54 that right here so D bounces in our
  • 00:35:57 helpers here and what we don't want to
  • 00:36:01 do is every single time the value
  • 00:36:03 changes go to the data base on firebase
  • 00:36:07 and update it because what that means is
  • 00:36:10 as the users typing in their text every
  • 00:36:13 single time they type a letter or
  • 00:36:14 character or a backspace or anything at
  • 00:36:17 all it's going to make an HTTP request
  • 00:36:19 to the database and that's going to get
  • 00:36:20 a little crazy so what we want to do is
  • 00:36:23 we want to wait for the user to stop
  • 00:36:26 typing for one-and-a-half seconds before
  • 00:36:28 we call the database and what this
  • 00:36:31 allows us to do is be a lot more
  • 00:36:32 efficient with with our resources so
  • 00:36:36 this is called debouncing and we are
  • 00:36:42 basically this helpers let's go back to
  • 00:36:45 it so I can show you this helpers
  • 00:36:48 function debounce
  • 00:36:50 is going to take a function okay so
  • 00:36:52 that's why we're passing our update
  • 00:36:54 function to our debounce function and
  • 00:36:57 what's gonna happen is whenever we're
  • 00:36:59 typing each time it tries to call update
  • 00:37:02 again it's gonna basically in essence
  • 00:37:05 cancel the last one until the user stops
  • 00:37:10 typing for at least 1.5 seconds and when
  • 00:37:13 they stop typing for 1.5 seconds the
  • 00:37:15 function will actually go all
  • 00:37:17 and update will complete so hopefully
  • 00:37:21 that makes sense so the second parameter
  • 00:37:22 that we want to pass to this to bounce
  • 00:37:24 is the amount of time and like I said
  • 00:37:26 1.5 seconds which is going to be fifteen
  • 00:37:28 hundred milliseconds so what is it we
  • 00:37:32 want to actually do with our update
  • 00:37:36 function well for now I just want to so
  • 00:37:39 will say come back later for now all I
  • 00:37:43 want to do is log lock some stuff so I
  • 00:37:45 can demonstrate the debouncing effect so
  • 00:37:48 we'll just come in here and say it
  • 00:37:49 console dot log updating database and
  • 00:37:56 let's see if this works the first time
  • 00:37:58 through alright so I'm coming in here
  • 00:38:01 into my text editor and I'm just typing
  • 00:38:04 some stuff I'm typing some stuff typing
  • 00:38:08 typing typing and now I'm going to stop
  • 00:38:09 typing okay you saw that I stopped
  • 00:38:11 typing for one-and-a-half seconds and
  • 00:38:14 then this function appeared it did not
  • 00:38:15 appear 20 times since I typed you know
  • 00:38:19 20 times or whatever it only appeared
  • 00:38:21 once and it waited for me to stop typing
  • 00:38:23 so that's that is something that I
  • 00:38:27 wanted to teach you guys as debouncing
  • 00:38:29 and it's very important for this
  • 00:38:30 tutorial especially because we're
  • 00:38:31 updating a database through the use of a
  • 00:38:35 user typing so that can you know if we
  • 00:38:37 have hundreds and hundreds or thousands
  • 00:38:39 and thousands of users and we're
  • 00:38:40 updating the database every single time
  • 00:38:42 a user types of key that's gonna get out
  • 00:38:44 of hand so we're gonna use debouncing in
  • 00:38:46 this tutorial okay so now what I want to
  • 00:38:50 do is start making this look a little
  • 00:38:52 better so I demonstrated you know what
  • 00:38:54 react quill does and you know a little
  • 00:38:56 bit about debouncing so what I want to
  • 00:38:59 do now is I want to start focusing on
  • 00:39:01 getting the sidebar component set up and
  • 00:39:04 we already went through getting items
  • 00:39:08 from the database on you know as soon as
  • 00:39:11 we load the app we get all of the notes
  • 00:39:13 from the database so since we already
  • 00:39:15 have access to the notes we might as
  • 00:39:17 well go ahead and start working on our
  • 00:39:18 sidebar to display those notes so go
  • 00:39:23 ahead and go to your sidebar component
  • 00:39:26 sidebar j/s and let's go ahead and get
  • 00:39:29 started work
  • 00:39:31 this now the first thing that we want to
  • 00:39:34 do is go ahead and go under our super
  • 00:39:36 inside of the constructor and say this
  • 00:39:37 state is equal to and we want to put an
  • 00:39:43 adding note and we'll set that equal to
  • 00:39:45 false and we will put a title which we
  • 00:39:52 will set to null by default cool so
  • 00:39:57 let's go ahead and destructor a couple
  • 00:39:59 of property variables so inside of here
  • 00:40:03 go ahead and prepare this inside of
  • 00:40:06 these curly braces the variables that we
  • 00:40:08 wanted to structure out are gonna be
  • 00:40:10 notes
  • 00:40:10 classes and selected note index now
  • 00:40:17 we're not passing these props yet so
  • 00:40:19 since we're not passing these properties
  • 00:40:21 yet it's we're probably gonna get an
  • 00:40:24 error if not then that's great but we'll
  • 00:40:28 go and we'll actually pass nulls right
  • 00:40:31 now so let's go to the let's go to the
  • 00:40:35 app KS and let's look we have notes
  • 00:40:38 classes is automatically passed in
  • 00:40:40 through with styles and we have selected
  • 00:40:42 note index so let's go ahead and pass
  • 00:40:44 those two in now we have selected note
  • 00:40:47 index so we can just go ahead and go
  • 00:40:50 here inside of our sidebar component
  • 00:40:52 element we can say selected note index
  • 00:40:55 is equal to this state dot selected note
  • 00:40:59 index I'm gonna put this on its own line
  • 00:41:02 and then the other one was notes which
  • 00:41:07 we also have so notes is equal to this
  • 00:41:12 dot state dot notes and so now we won't
  • 00:41:16 get an error so now that we have these
  • 00:41:20 destructured inside of our sidebar j/s
  • 00:41:22 file I want to go ahead and remove hello
  • 00:41:24 from the sidebar and I want to give our
  • 00:41:28 our parent div here a class name so we
  • 00:41:32 have a class name and we use the classes
  • 00:41:34 object classes sidebar
  • 00:41:38 container alright so inside of here I
  • 00:41:42 want to go ahead and add a button and
  • 00:41:45 it's gonna be a button with a capital B
  • 00:41:49 and that's because it is a if we go up
  • 00:41:51 here I can show you a it is a component
  • 00:41:55 from the material UI core and we're
  • 00:41:58 going to use that because it's going to
  • 00:41:59 just make it look a little better by
  • 00:42:00 default so we're gonna add a few things
  • 00:42:02 here we're gonna have it on click and
  • 00:42:05 the on click function that we're going
  • 00:42:08 to provide here we're going to write
  • 00:42:09 that function so for now we'll just call
  • 00:42:11 a new note BTN click and that's a
  • 00:42:15 function we're going to write in just a
  • 00:42:16 moment so keep that in mind we'll get
  • 00:42:17 right back to that I'm go ahead and add
  • 00:42:19 a class name and that class name will be
  • 00:42:22 classes dot new note BTN and inside of
  • 00:42:31 here I'm just gonna put the text to say
  • 00:42:34 new note we'll change this in just a
  • 00:42:35 second so let me go ahead and let's add
  • 00:42:37 this new note button click function
  • 00:42:40 underneath the render function so here
  • 00:42:43 we will say new note BTN click is equal
  • 00:42:47 to a function and for now I'm just gonna
  • 00:42:50 have it say console dot log and I'm
  • 00:42:53 gonna say new BTN clicked cool so let's
  • 00:42:58 see what we ended up with so when we
  • 00:43:00 come back over here you can see that we
  • 00:43:02 have this sidebar here and that's
  • 00:43:04 because we already have the styles for
  • 00:43:06 it we just added the container class
  • 00:43:08 here which are all inside of the Styles
  • 00:43:10 JS file so we we have the sidebar
  • 00:43:14 container and we have this new notes
  • 00:43:16 button here I'm going to clear this and
  • 00:43:18 I'm going to click it you can see now it
  • 00:43:19 says new BTN clicked so we know the
  • 00:43:22 button is working so below the button
  • 00:43:26 still inside of the div container but
  • 00:43:29 below the button we're gonna put two
  • 00:43:31 curly braces and what we want to do is
  • 00:43:34 we want to have the ability to add a new
  • 00:43:37 note and if we click on new note button
  • 00:43:42 we want the new note input to show up so
  • 00:43:48 let's go ahead and say if this
  • 00:43:51 State DOT adding note put a question
  • 00:43:55 mark after we're gonna use our ternary
  • 00:43:56 operator as you can see we have this
  • 00:43:58 adding note slice of state which is
  • 00:44:00 false by default so by default this is
  • 00:44:05 not going to show up so that's good
  • 00:44:07 because we don't want the user to
  • 00:44:09 suddenly see add a new note unless they
  • 00:44:11 go and explicitly click that button so
  • 00:44:16 if this does state that adding note
  • 00:44:18 we're gonna do some stuff we're gonna
  • 00:44:20 return a div you know let me go ahead
  • 00:44:25 and get that otherwise we're gonna just
  • 00:44:27 go ahead and return null okay so let's
  • 00:44:30 go ahead go inside of this div and put
  • 00:44:32 in the stuff that we actually want to
  • 00:44:33 return if this not adding state this
  • 00:44:36 does state that adding note is true so
  • 00:44:38 the div is gonna have an input an input
  • 00:44:42 and the type of the input type is equal
  • 00:44:47 to text and a class name is going to be
  • 00:44:53 equal to classes dot new note input and
  • 00:44:59 we're gonna have an on key up function
  • 00:45:02 but first let's add a placeholder
  • 00:45:04 placeholder and the placeholder is just
  • 00:45:07 the text that's going to be inside of
  • 00:45:09 the input before the user starts to
  • 00:45:11 enter text inside of it manually so
  • 00:45:14 we'll just say enter note title and
  • 00:45:17 again we will have a non key up function
  • 00:45:20 on key up and so whenever the user
  • 00:45:24 starts typing in there whenever they
  • 00:45:26 lift their finger off of a key a
  • 00:45:27 function will get fired and it gets
  • 00:45:29 passed the event by default and we want
  • 00:45:31 to pass that event to our own function
  • 00:45:33 which we will call this stuff update
  • 00:45:35 title and we will pass an e dot target
  • 00:45:40 value which is going to be the target
  • 00:45:43 element of the event that got fired off
  • 00:45:45 that we're passing in from here and the
  • 00:45:47 value of that so we're going to pass
  • 00:45:49 that to our update title function which
  • 00:45:51 for now come down here update title is
  • 00:45:55 equal to a function that takes some text
  • 00:45:57 so just put text txt and for now just
  • 00:46:01 console.log
  • 00:46:03 and I'm going to say here it is and I'm
  • 00:46:09 going to display the text that we passed
  • 00:46:11 update title okay so let's see here go
  • 00:46:15 ahead and I think it's safe to save this
  • 00:46:18 let's find out
  • 00:46:20 clear this see what happens when I click
  • 00:46:22 this we got new BTN clicked but it looks
  • 00:46:25 like oh yeah that's right we have to
  • 00:46:27 actually flip that variable so when we
  • 00:46:30 have new BTN clicked we need to go ahead
  • 00:46:33 new note BTN clicked we need to go ahead
  • 00:46:35 and flip that variable in the state the
  • 00:46:38 specifically the this state adding note
  • 00:46:42 because otherwise if we don't flip that
  • 00:46:44 to true this will never display right
  • 00:46:46 here so we need to go ahead and do that
  • 00:46:48 alright this set state and then inside
  • 00:46:54 of here we want to go ahead and update
  • 00:46:55 adding note and what we want to set it
  • 00:46:58 to is not the state dot adding note so
  • 00:47:02 if that's false it'll flip it to true if
  • 00:47:06 it's true it'll flip it to false it's
  • 00:47:07 just saying whatever this state to
  • 00:47:10 adding note is we just want it to be the
  • 00:47:12 opposite and we also want to reset the
  • 00:47:16 title and the reason why we want to
  • 00:47:19 reset the title is because when we're
  • 00:47:20 adding a new note if we start typing in
  • 00:47:22 a title and then we want to stop adding
  • 00:47:24 a note when we go to add another note we
  • 00:47:27 don't want that previous title to still
  • 00:47:29 be in the input so we're just gonna
  • 00:47:30 reset the title and save let's see if
  • 00:47:33 that works for us ok let's come over to
  • 00:47:35 new note and when I click it you can see
  • 00:47:36 now I have this input here and when I
  • 00:47:38 start to type inside of it it's saying
  • 00:47:40 it is actually logging it here as we
  • 00:47:43 expected and then when I click new note
  • 00:47:45 it makes it go away because we're
  • 00:47:48 flipping that variable when I click it
  • 00:47:50 again you can see it's empty that's
  • 00:47:51 because we're resetting that title
  • 00:47:53 that's exactly what we wanted to do but
  • 00:47:55 here's the problem when I click new note
  • 00:47:57 it still says a new note I want it to
  • 00:47:59 say cancel so I wanted to say new note
  • 00:48:02 here because it makes sense I want to
  • 00:48:04 click that I want to create a new note
  • 00:48:06 but now I don't want it to say new note
  • 00:48:08 any more I wanted to say cancel so what
  • 00:48:12 we want to do is we want to go inside
  • 00:48:14 where we put the text for that button
  • 00:48:16 where it says new note hee
  • 00:48:17 let's put some JavaScript in there so
  • 00:48:19 two curly braces and we want to do a
  • 00:48:21 ternary operator and we'll say this
  • 00:48:25 state that adding note so if that's true
  • 00:48:28 we want to go ahead and say cancel
  • 00:48:31 otherwise we want to go ahead and say
  • 00:48:34 new note so let's save that and it says
  • 00:48:38 new note and when I click it now it says
  • 00:48:39 cancel okay that's that's exactly what
  • 00:48:43 we want it to do cool so let's go ahead
  • 00:48:47 and move on all right so now what we
  • 00:48:52 want to do is we have that input we have
  • 00:48:55 the enter note title input let's go
  • 00:48:58 ahead and go directly underneath that
  • 00:49:00 and let's create another button with a
  • 00:49:01 capital v and we want to create our
  • 00:49:04 submit button so let's give it a class
  • 00:49:05 name is that equal to classes dot new
  • 00:49:09 note submit BTN all right I'm gonna put
  • 00:49:14 that on its own line make sure you guys
  • 00:49:16 can see everything and then I want to
  • 00:49:19 add an on click function and we're gonna
  • 00:49:25 call this dot new note whenever we click
  • 00:49:28 this button and we have to create this
  • 00:49:29 function but for now we'll go ahead and
  • 00:49:32 put some text in here that says submit
  • 00:49:33 note cool so let's create a function
  • 00:49:37 called new note and for now just console
  • 00:49:43 dot log let's just log the entire state
  • 00:49:46 okay so we'll save this we'll come back
  • 00:49:49 over here
  • 00:49:51 clear this console so it's clean new
  • 00:49:54 note now you can see the submit note
  • 00:49:57 button is here I'll start typing in a
  • 00:49:59 title and when I click Submit now the
  • 00:50:02 state is adding note is true and the
  • 00:50:05 title is null the reason why the title
  • 00:50:07 is null is because inside of update
  • 00:50:09 title we are logging instead of setting
  • 00:50:12 the state so let's go ahead and set the
  • 00:50:15 state
  • 00:50:23 alright so the title the idol we will
  • 00:50:27 simply set that to text and then we will
  • 00:50:30 save
  • 00:50:30 okay so let's demo this one more time
  • 00:50:33 say this oops this is a title and I'm
  • 00:50:38 gonna click Submit note and you can see
  • 00:50:40 now that the state is properly updated
  • 00:50:43 cool so there we go cool so I want to
  • 00:50:48 come in here and I want to go ahead and
  • 00:50:53 start working on the list of all of the
  • 00:50:56 notes on the side so let's go ahead and
  • 00:50:59 do that so what where we want to be is
  • 00:51:02 outside of these curly braces right here
  • 00:51:04 we want to go beyond that and we want to
  • 00:51:08 add a list element with a capital L and
  • 00:51:11 then inside of the list element we want
  • 00:51:13 to put two curly braces because what
  • 00:51:15 we're gonna do is we're going to map all
  • 00:51:19 of the notes that we get from the props
  • 00:51:22 so all of these notes here that we're
  • 00:51:23 passing in from the apt is we want to
  • 00:51:26 take all of those notes and map those to
  • 00:51:28 actual elements so again if you don't if
  • 00:51:33 you're not super comfortable with the
  • 00:51:35 map function in JavaScript I do have a
  • 00:51:37 tutorial for it that I think will really
  • 00:51:39 help you guys understand the map
  • 00:51:41 function in detail go ahead and look in
  • 00:51:44 the description for that video and then
  • 00:51:46 come back to this if you are familiar
  • 00:51:49 with in the map function and let's go
  • 00:51:51 ahead and move on so we're gonna say
  • 00:51:53 notes dot map and we will have two
  • 00:51:58 parameters here we will have note so for
  • 00:52:01 each note and its index we're gonna go
  • 00:52:05 ahead and return some HTML so I'm gonna
  • 00:52:11 get rid of this curly brace
  • 00:52:12 I mean semicolon get rid of these
  • 00:52:14 semicolons here so I'm gonna have a div
  • 00:52:18 and in react whenever we map or whenever
  • 00:52:23 we're iterating through and creating a
  • 00:52:24 bunch of elements we need to give a key
  • 00:52:27 to the parent and I'm just going to use
  • 00:52:30 our index as the key
  • 00:52:32 and what we want to do is for each and
  • 00:52:36 every single note we want to create a
  • 00:52:37 sidebar sidebar item component and site
  • 00:52:43 of our item component is going to take
  • 00:52:44 several properties so let's go ahead and
  • 00:52:47 start working on those props so the
  • 00:52:49 first one is going to be note and that's
  • 00:52:52 going to be equal to the note we're on
  • 00:52:55 the second one is going to be index and
  • 00:52:59 that's going to be equal to the index
  • 00:53:01 we're on and I put a comma here which I
  • 00:53:04 shouldn't have all right the then we're
  • 00:53:08 gonna have selected note index which is
  • 00:53:11 going to equal selected note index which
  • 00:53:16 we're getting right here so we have
  • 00:53:20 direct access to that then we're gonna
  • 00:53:22 say select note which is gonna be a
  • 00:53:24 function property here
  • 00:53:26 and we're just gonna say this does
  • 00:53:28 select note which I believe we do not
  • 00:53:31 have implemented yet so let's go ahead
  • 00:53:34 and create select note it's just gonna
  • 00:53:37 be a function that for now I'm just
  • 00:53:39 gonna say console dot log select note
  • 00:53:44 just to get that out of the way really
  • 00:53:45 quick and we'll come back to it then
  • 00:53:48 we're also gonna have a delete note
  • 00:53:49 function which will do the exact same
  • 00:53:51 thing that we just did here this dot
  • 00:53:55 delete note and we'll go and I'm just
  • 00:53:59 gonna copy this function and paste it
  • 00:54:02 and then replace with delete okay
  • 00:54:08 cool so now we have a sidebar item
  • 00:54:11 inside of a div but underneath the
  • 00:54:13 sidebar item we want to go ahead and put
  • 00:54:15 a divider and all the divider is is it's
  • 00:54:19 just gonna be a small dividing line
  • 00:54:21 between each of these sidebar item
  • 00:54:23 components so that you can distinguish
  • 00:54:26 you can distinguish them basically so
  • 00:54:29 I'm gonna save and let's just take a
  • 00:54:30 look and see what we've got so far we've
  • 00:54:33 got an error so it says cannot read
  • 00:54:34 property map of null and the reason why
  • 00:54:36 we are getting this is because let's see
  • 00:54:39 it's go back up here we're mapping
  • 00:54:41 through notes and map is a function of
  • 00:54:45 arrey object okay so if notes is null
  • 00:54:48 then we're calling map on something that
  • 00:54:50 does not have a function called map and
  • 00:54:52 for now an editor notes
  • 00:54:56 sorry not an editor in apt is notes as
  • 00:54:58 null we as soon as we load the sidebar
  • 00:55:04 component we're passing in a null now
  • 00:55:07 later on you can see that notes is being
  • 00:55:10 updated but this is asynchronous meaning
  • 00:55:12 that this isn't being so notes isn't
  • 00:55:16 being set until after we're calling map
  • 00:55:21 inside of the sidebar component and
  • 00:55:23 that's that's one of the frustrations
  • 00:55:25 that a lot of people have to deal with
  • 00:55:26 in JavaScript is the asynchronous aspect
  • 00:55:30 of it so let's go ahead and take care of
  • 00:55:33 this problem right now so in order to
  • 00:55:37 fix this little hiccup that we
  • 00:55:39 inevitably will have run into I don't
  • 00:55:42 want to go ahead and take this entire
  • 00:55:44 return statement and I want to cut some
  • 00:55:48 I cut it so that I can paste it and I'm
  • 00:55:50 gonna put an if statement here where I
  • 00:55:51 say if notes so in other words if notes
  • 00:55:55 is not null then I want to paste that
  • 00:55:58 return statement into there else if it
  • 00:56:03 is null I want to go ahead and return a
  • 00:56:07 small div that's just gonna say add a
  • 00:56:10 note exclamation point which you know
  • 00:56:15 this you'll probably never even see
  • 00:56:17 because even if the array itself is
  • 00:56:21 empty it's still gonna go down this
  • 00:56:25 route so in reality we could just put an
  • 00:56:28 empty div here so I'm just gonna
  • 00:56:29 actually just gonna actually put an
  • 00:56:31 empty div here instead and so what we're
  • 00:56:33 doing is we're saying if notes is not
  • 00:56:36 null then let's go ahead and do all this
  • 00:56:38 stuff and if notes is null we're just
  • 00:56:41 going to return an empty div and so
  • 00:56:42 what's gonna happen is inside of the
  • 00:56:44 Apps jet app.js file when it first
  • 00:56:47 renders the sidebar component notes is
  • 00:56:49 gonna be null because notes is null
  • 00:56:51 inside of the state by default then when
  • 00:56:54 this component didn't mount goes through
  • 00:56:56 and successfully retrieves all of the
  • 00:56:58 notes
  • 00:56:58 and sets the state know it's equal to
  • 00:57:00 notes this is gonna rerender with notes
  • 00:57:05 not being null and then it's gonna come
  • 00:57:08 back into this render statement notes
  • 00:57:10 will then not be null anymore and it
  • 00:57:12 will go ahead and call all of this and
  • 00:57:14 so map can actually be called on an
  • 00:57:17 empty array that's perfectly fine it
  • 00:57:19 just means we're not gonna have any
  • 00:57:20 sidebar item components that's the
  • 00:57:22 behavior we want if notes is null again
  • 00:57:25 map simply doesn't exist on norm so
  • 00:57:28 that's why we went ahead and create this
  • 00:57:30 else I hope that makes good sense for
  • 00:57:32 you guys so come back over here and
  • 00:57:34 refresh you see hello from the sidebar
  • 00:57:37 item and that's because we have one note
  • 00:57:40 inside of firebase so it's rendering out
  • 00:57:44 one sidebar item component and if we go
  • 00:57:46 to our sidebar item component you can
  • 00:57:48 see that all we're doing here is saying
  • 00:57:50 hello from the sidebar item so what we
  • 00:57:52 really need to do is go in and start
  • 00:57:55 working on our sidebar item component
  • 00:57:57 now okay so let's go ahead go to our
  • 00:58:00 sidebar item J's file go ahead and let's
  • 00:58:04 remove the constructor here because
  • 00:58:05 we're actually not going to be using any
  • 00:58:07 State inside of this sidebar item
  • 00:58:09 component only props so since we're only
  • 00:58:12 gonna be using props we can pretty much
  • 00:58:13 call this a stateless component although
  • 00:58:15 it's not by definition because it is
  • 00:58:17 going to be using the props so in a
  • 00:58:20 sense it's kind of a functional
  • 00:58:21 component so we'll go ahead and just
  • 00:58:23 call it a functional component so this
  • 00:58:26 is gonna be a functional component so
  • 00:58:27 the first thing that we want to do is
  • 00:58:29 inside of our render I'm going to get
  • 00:58:33 rid of this hello from the side of our
  • 00:58:35 item and put everything on woops put
  • 00:58:39 everything inside on its own line and
  • 00:58:45 indent it then at the top of the render
  • 00:58:48 function I'm going to go ahead and D
  • 00:58:49 structure out some stuff from this table
  • 00:58:53 props so if you remember we had a bunch
  • 00:58:57 of different props that we were passing
  • 00:58:59 in from the sidebar component we had a
  • 00:59:00 note index selected note index select
  • 00:59:02 note and delete know so let's go ahead
  • 00:59:04 and grab all of those so index note
  • 00:59:09 classes which is being passed in through
  • 00:59:12 with styles by default and selected note
  • 00:59:15 index cool so the delete note and select
  • 00:59:24 note we're not going to actually utilize
  • 00:59:25 inside of the render function we're
  • 00:59:27 going to utilize that elsewhere so we
  • 00:59:29 don't need to destructure that here cool
  • 00:59:32 so let's return and let's go ahead and
  • 00:59:35 say the key here let's just add a key
  • 00:59:37 here and we'll set that equal to index
  • 00:59:41 then let's put a list item in here and
  • 00:59:45 so what we're gonna say is for each
  • 00:59:47 sidebar item component that we have it's
  • 00:59:49 going to be a a list item which is a
  • 00:59:52 material UI component so if we look back
  • 00:59:56 in here we have this list component
  • 00:59:58 which is also a material UI component
  • 01:00:01 and we're looping through in creating
  • 01:00:03 list items so let's give a class name
  • 01:00:07 whoops got to go inside of the tag here
  • 01:00:11 let's give a class name and we're gonna
  • 01:00:14 set it equal to classes dot list item
  • 01:00:17 book list item and then let's give it a
  • 01:00:23 selected which I'll explain that in just
  • 01:00:26 a second
  • 01:00:27 selected note index is equal to index
  • 01:00:31 okay so let's go ahead and explain this
  • 01:00:33 so selected is a property of the list
  • 01:00:36 item component which if this selected
  • 01:00:40 variable is true then it's going to be
  • 01:00:44 highlighted and that's basically it and
  • 01:00:46 so what we're gonna say is we want it to
  • 01:00:48 be considered selected if selected note
  • 01:00:51 index is equal to our current index and
  • 01:00:54 this index is actually our loop index
  • 01:00:57 that we have right here so if the
  • 01:01:00 current selected note index is equal to
  • 01:01:03 the current item Ron then we can safely
  • 01:01:06 say that this is the one that is
  • 01:01:09 selected okay so let's go ahead and add
  • 01:01:12 aligned items and let's set that equal
  • 01:01:15 to flex start we can just use a normal
  • 01:01:19 string here celebrate
  • 01:01:21 alright so let's add a div okay so
  • 01:01:25 inside of this list item will have a div
  • 01:01:27 and inside of this div actually let's
  • 01:01:30 add some class name is that a class name
  • 01:01:32 here class is dot and we'll call this
  • 01:01:37 text section and let's add an on click
  • 01:01:41 on click let me just try to get
  • 01:01:45 everything on it on its own line so you
  • 01:01:47 can see everything clearly on click and
  • 01:01:51 we're gonna pass a function so we're
  • 01:01:52 gonna say this dot select note select
  • 01:01:58 note and it'll take the note and the
  • 01:02:02 index okay so we have this class name
  • 01:02:05 and on click afford the div here and
  • 01:02:07 let's go ahead and inside of this div
  • 01:02:11 use a list item text component and again
  • 01:02:16 this is just this is just from material
  • 01:02:18 UI right here is these are just
  • 01:02:21 components that come from material UI
  • 01:02:23 that just make making things look good
  • 01:02:27 really easy so all of these things tend
  • 01:02:31 to just use properties so we're gonna go
  • 01:02:33 ahead and add them our primary is going
  • 01:02:38 to be our note dot title and our
  • 01:02:42 secondary so it's going to have primary
  • 01:02:44 and secondary text our secondary text
  • 01:02:47 now this is where we get to use another
  • 01:02:48 one of our help for helper functions so
  • 01:02:50 for now I'm not gonna use it
  • 01:02:52 and I'll show you why we need it in just
  • 01:02:54 a second so note body note body dot sub
  • 01:02:58 string sub string 0 30 plus dot dot dot
  • 01:03:08 okay so I'm gonna go ahead and explain
  • 01:03:10 what I'm doing here so note dot body
  • 01:03:13 could be a massive string because it's
  • 01:03:16 the entire body of the note it's all of
  • 01:03:18 the text inside of the note so we don't
  • 01:03:20 want to display that on the sidebar it's
  • 01:03:23 just too much text so I'm taking the
  • 01:03:25 first 30 characters of that and then if
  • 01:03:28 it's more than 30 characters I'm also
  • 01:03:29 adding dot dot dot at the end of that so
  • 01:03:32 let's go ahead and
  • 01:03:33 let's see what happens if I save now
  • 01:03:34 let's see if we can see perfect okay
  • 01:03:38 so test note from firebases the title
  • 01:03:40 and the secondary text or so the test
  • 01:03:44 note from firebase is our primary you
  • 01:03:46 can see primary is no title and our
  • 01:03:48 secondary is this substring here as you
  • 01:03:51 can see it's working as expected but as
  • 01:03:52 you can see this is HTML and the reason
  • 01:03:56 why it's HTML again is because in
  • 01:03:58 firebase we are storing this as HTML
  • 01:04:01 react quill actually stores the value of
  • 01:04:05 whatever you're typing inside of here as
  • 01:04:06 HTML so we have that helper j/s file and
  • 01:04:10 the second function here is called
  • 01:04:13 remove HTML tags and that is exactly
  • 01:04:15 what we're going to use here to get rid
  • 01:04:17 of that that HTML so let's go ahead and
  • 01:04:20 take this section here and cut and then
  • 01:04:24 we're gonna say remove HTML tags and
  • 01:04:26 pass that as the parameter save it come
  • 01:04:31 back over here and now you can see it
  • 01:04:32 just says hello world dot instead of at
  • 01:04:35 HTML cool so what we want to do is under
  • 01:04:41 our list item text we have the closing
  • 01:04:45 div tag cool so underneath the closing
  • 01:04:47 div tag we want to create a delete icon
  • 01:04:50 that's the capital D delete icon and we
  • 01:04:55 want to add an on click function
  • 01:04:57 obviously and the on click function is
  • 01:05:02 going to be this dot delete note and
  • 01:05:11 we'll give it a class name as well
  • 01:05:17 so the class name is going me classes
  • 01:05:19 dot delete icon
  • 01:05:21 make sure you don't make sure it's
  • 01:05:24 spelled exactly like this because if it
  • 01:05:26 has a capital D as you're creating these
  • 01:05:28 class names just if you are wondering if
  • 01:05:31 you're spelling it correctly you can
  • 01:05:33 look at the video of course but you can
  • 01:05:34 also go to your Styles j/s file and just
  • 01:05:37 look and see exactly how it's spelled
  • 01:05:41 here so you can see which classes you
  • 01:05:42 have available and all of that inside of
  • 01:05:44 your Styles dot J's file for each
  • 01:05:45 component so I'm gonna save that come
  • 01:05:48 back over here and now you can see there
  • 01:05:51 is a delete icon which for now if I
  • 01:05:53 click it it's gonna break us because we
  • 01:05:56 have not implemented this delete note so
  • 01:05:59 we have two functions that we need to
  • 01:06:00 implement we have to implement our
  • 01:06:02 delete note and select note functions so
  • 01:06:04 underneath our render function let's go
  • 01:06:06 ahead and create a select note function
  • 01:06:10 which will take an N and an eye which is
  • 01:06:13 note and index and you can see we are
  • 01:06:15 already passing note in index to our
  • 01:06:17 select note function so N and I and
  • 01:06:20 we're just gonna say this dot props dot
  • 01:06:23 select no and we're gonna pass and and I
  • 01:06:28 to that and so this dot props that
  • 01:06:30 select note if we go back we can see
  • 01:06:33 that we are in fact sending a property
  • 01:06:35 over called select note which is equal
  • 01:06:37 to this da select note which is a
  • 01:06:39 function inside of the sidebar component
  • 01:06:41 which is just logging select note ok
  • 01:06:45 keep that in mind so I will actually
  • 01:06:48 save this and let's demonstrate that so
  • 01:06:52 if I click this note you can see now it
  • 01:06:54 says select note and that is in fact
  • 01:06:55 coming from the sidebar component so
  • 01:06:58 it's KITT it's calling that parent
  • 01:06:59 function now we need to add delete note
  • 01:07:04 delete no which is gonna take note
  • 01:07:06 whoops
  • 01:07:07 spell that nope and you can see when we
  • 01:07:11 call delete note here this dot delete no
  • 01:07:14 we are passing the current note in so
  • 01:07:17 what we want to do is we don't want to
  • 01:07:20 just let the lead the the user
  • 01:07:22 accidentally delete notes so if they
  • 01:07:24 accidentally click the trash can icon
  • 01:07:26 and it deletes their entire you
  • 01:07:28 no poem that they've been writing for a
  • 01:07:30 month they'd be pretty mad so what we
  • 01:07:32 want to do is say if window dot confirm
  • 01:07:36 and I'm gonna put two back ticks here
  • 01:07:40 and I've made a lot of tutorials in the
  • 01:07:42 past and people do get pretty confused
  • 01:07:43 about this so I want to take a second to
  • 01:07:45 really explain this
  • 01:07:46 the backticks tend to be underneath the
  • 01:07:50 escape button and above the tab button
  • 01:07:54 on a standard keyboard
  • 01:07:55 they are backticks they are not
  • 01:07:57 apostrophes they are not quotation marks
  • 01:07:59 they're backticks and what the back
  • 01:08:01 ticks allow you to do is they allow you
  • 01:08:03 to write in a string but also allow you
  • 01:08:06 to add JavaScript to that string and
  • 01:08:08 then it renders it out afterwards so
  • 01:08:11 please make sure if you if this part is
  • 01:08:14 confusing to you just make sure you're
  • 01:08:15 using the back ticks before posting a
  • 01:08:18 comment so let's say are you sure you
  • 01:08:22 want to delete : and then this is where
  • 01:08:26 we add our JavaScript and then in order
  • 01:08:28 to do that we just put a dollar sign and
  • 01:08:29 opening the open and closing curly brace
  • 01:08:32 and we'll say note that title and see it
  • 01:08:35 just takes this JavaScript and adds it
  • 01:08:37 to this string essentially so if that's
  • 01:08:40 true this dot props dot delete note note
  • 01:08:47 and I'll save and I'll show you what
  • 01:08:50 this does so I'm gonna click delete note
  • 01:08:52 it says are you sure you want to delete
  • 01:08:54 test note from firebase I click yeah I
  • 01:08:57 do want to delete that and now you can
  • 01:08:59 see it log is delete know since in the
  • 01:09:02 side bar component we're just logging
  • 01:09:04 delete note all right so we got through
  • 01:09:08 the side bar item component so we are
  • 01:09:10 getting pretty close here we're actually
  • 01:09:12 getting to almost a functional Evernote
  • 01:09:15 clone so if we go back to our sidebar
  • 01:09:18 component we what we don't want to do is
  • 01:09:22 we don't want to just log stuff we want
  • 01:09:24 to actually select notes and delete
  • 01:09:26 notes so if we go to our app.js file in
  • 01:09:29 the sidebar component you can see we
  • 01:09:31 have a select selected note index and we
  • 01:09:34 have notes as props but what we really
  • 01:09:36 also need is we also need a
  • 01:09:40 of functions that we need to pass as
  • 01:09:41 props from the app J's file and those
  • 01:09:44 functions are going to be delete note
  • 01:09:46 new note and select note so let's go
  • 01:09:49 ahead and create those functions inside
  • 01:09:52 of the app dot J's file go ahead and
  • 01:09:54 create those functions we'll add the
  • 01:09:56 functionality for those functions inside
  • 01:09:58 of the app dot J's file and then we'll
  • 01:10:00 go back into the sidebar component and
  • 01:10:02 remove these console dot log statements
  • 01:10:05 and actually implement the app j/s
  • 01:10:07 functions okay let's go ahead and do
  • 01:10:09 that okay so let's go to our app.js file
  • 01:10:12 and you can see our sidebar component
  • 01:10:14 here let's go ahead and start adding in
  • 01:10:17 the props so delete note we'll save this
  • 01:10:21 dot delete note which doesn't exist yet
  • 01:10:25 select no nope not selected no we want
  • 01:10:28 to have make sure it's called select
  • 01:10:29 note because it's a function and we will
  • 01:10:33 go ahead and give it this select note
  • 01:10:36 which does not exist yet and then
  • 01:10:38 finally we will have new note new note
  • 01:10:41 which we will again set to this dot new
  • 01:10:44 note which does not exist yet cool so
  • 01:10:50 let's make them all exist now so let's
  • 01:10:53 see what do we want to start with I hmm
  • 01:10:56 I think select note let's do select note
  • 01:11:00 first and the reason why I want to do
  • 01:11:01 select note first is because that way we
  • 01:11:03 can select the note we can show that the
  • 01:11:06 selected property for the sidebar items
  • 01:11:08 list items is working correctly and also
  • 01:11:12 demonstrate the text will have to go
  • 01:11:15 into the editor component in order to do
  • 01:11:17 a few small things so that when we
  • 01:11:18 select this that text actually appears
  • 01:11:21 over here so I want to go ahead and
  • 01:11:23 knock that out so that we can focus on
  • 01:11:25 the other stuff so let's go ahead and go
  • 01:11:28 to our select note let's create that
  • 01:11:30 select note and we will expect select
  • 01:11:37 note to take a note and an index whoa
  • 01:11:40 and let's just say this set state
  • 01:11:46 and we'll update some state here and
  • 01:11:48 we'll update the selected note index
  • 01:11:50 which we have the index so index and
  • 01:11:54 then select a note selected note and we
  • 01:11:59 will set that equal to note so I think
  • 01:12:01 we already have select note implemented
  • 01:12:04 inside of the sidebar item so let's go
  • 01:12:06 to the sidebar item and just verify that
  • 01:12:08 select note we are calling that and then
  • 01:12:11 inside of the sidebar select note is
  • 01:12:13 just logging so what we want to do is
  • 01:12:15 actually call this stop props this stop
  • 01:12:18 props select note and we want to pass in
  • 01:12:21 the note and the index now let's just
  • 01:12:25 make sure that order is correct it is
  • 01:12:27 note and index so it's in that order
  • 01:12:31 note and index and we need to actually
  • 01:12:36 for select note we actually need to
  • 01:12:37 accept n and I and inside of the sidebar
  • 01:12:40 item component you can see we are in
  • 01:12:42 fact passing the note and the index
  • 01:12:43 that's what N and I stand for we are
  • 01:12:45 passing that so we just need to make
  • 01:12:47 sure that we accept those as arguments
  • 01:12:49 here in this function inside the sidebar
  • 01:12:51 and once we save in theory this should
  • 01:12:55 this should work now away says note is
  • 01:12:58 not defined that's in the sidebar line
  • 01:13:00 74 do yes because it's N and I not note
  • 01:13:04 an index so save that that air should go
  • 01:13:08 away correct so what happens when I
  • 01:13:10 click this when I click that now you can
  • 01:13:13 see it's highlighted so we know that it
  • 01:13:15 is actually updating the state correctly
  • 01:13:18 because now we know that this is
  • 01:13:19 selected so it's it's working what's not
  • 01:13:22 working yet is we're not displaying that
  • 01:13:25 information over here so let's go ahead
  • 01:13:27 and go into our editor component and
  • 01:13:30 start we need to do a few things to
  • 01:13:34 actually display the currently selected
  • 01:13:36 note so let's see let's start with the
  • 01:13:40 app.js file because we're gonna have to
  • 01:13:41 pass in some properties to our editor
  • 01:13:44 component I know this is all over the
  • 01:13:46 place guys so just bear with me there's
  • 01:13:48 a lot going on in this tutorial it is
  • 01:13:50 kind of an intermediate level tutorial
  • 01:13:52 and there's a lot that needs to be
  • 01:13:54 covered so that's why I'm kind of moving
  • 01:13:56 quickly and sporadically but this is the
  • 01:13:58 kind of
  • 01:13:58 this is the way I actually work when I
  • 01:14:00 write code is I I'm always going over
  • 01:14:04 the place I'm not focused on one
  • 01:14:06 particular thing I'm focused on the task
  • 01:14:08 that I'm trying to complete which could
  • 01:14:10 be in six different files so it kind of
  • 01:14:13 can seem like I'm all over the place but
  • 01:14:14 in reality I'm just focused on one task
  • 01:14:17 at a time here so what we want to pass
  • 01:14:20 to the editor component is a selected
  • 01:14:24 note which not select no selected note
  • 01:14:28 and we want to make sure that we set
  • 01:14:31 that equal to the state selected note
  • 01:14:35 and then we want to pass a selected note
  • 01:14:38 index which will be this state dot
  • 01:14:43 selected note index and then finally we
  • 01:14:46 want to pass notes which is this state
  • 01:14:49 dot notes now if we don't have a
  • 01:14:53 selected note if we have not selected a
  • 01:14:56 note at all then we don't want to render
  • 01:14:58 this editor component whatsoever so
  • 01:15:00 let's cut that and then let's put some
  • 01:15:02 curly braces and say this state dot
  • 01:15:04 selected note question mark so a ternary
  • 01:15:07 operator go ahead and render that out :
  • 01:15:10 in other words else we're just going to
  • 01:15:13 return null cool so I will save that and
  • 01:15:18 let's see what happens when I click this
  • 01:15:20 so I click it and now this appears so we
  • 01:15:23 know again that our this dot state
  • 01:15:25 selected note piece of state is updating
  • 01:15:29 correctly so I just want to demonstrate
  • 01:15:30 that one more time we do not have the
  • 01:15:32 editor here I click this now the editor
  • 01:15:34 is there cool so now we just need to go
  • 01:15:38 into our editor component and actually
  • 01:15:40 accept those properties and begin
  • 01:15:46 displaying them okay so where we want to
  • 01:15:50 start is you can see we have value and
  • 01:15:52 value is the value of the react quill so
  • 01:15:56 it's whatever is inside of here and it's
  • 01:15:58 HTML it's one big string of HTML that's
  • 01:16:01 what value is so it uses that value to
  • 01:16:04 render out all this stuff now right now
  • 01:16:07 this state text is always an empty
  • 01:16:10 string so
  • 01:16:12 what we have to do is we have to go in
  • 01:16:14 and take we have to update the this date
  • 01:16:20 text state with whatever property we
  • 01:16:23 have passed in so let's go ahead and
  • 01:16:26 implement some lifecycle hooks to do
  • 01:16:28 that but we're gonna have to implement
  • 01:16:30 two lifecycle hooks and I will explain
  • 01:16:33 that in just a second so let's just go
  • 01:16:36 ahead and implement it and then I'll
  • 01:16:37 explain why we're doing it this way so
  • 01:16:39 component did mount okay I explained
  • 01:16:43 lifecycle hooks a little earlier so
  • 01:16:47 we'll say this set state and we're gonna
  • 01:16:50 go ahead and set all the state we're
  • 01:16:51 gonna say this text is going to simply
  • 01:16:54 be this dot state dot I'm sorry this dot
  • 01:16:57 props this top props that selected note
  • 01:17:01 body then we also have a title which is
  • 01:17:07 going to be this dot props dot selected
  • 01:17:09 note dot title and then finally our ID
  • 01:17:14 slice of state is going to be this top
  • 01:17:17 props dot selected note ID cool so when
  • 01:17:27 we mount the component when we first
  • 01:17:29 mount it it's gonna set this state so
  • 01:17:32 I'm going to save it and I want to see
  • 01:17:33 what happens when we mount it I click it
  • 01:17:36 now you can see hello world is being
  • 01:17:39 rendered as an h1 tag or a heading one
  • 01:17:42 here it's being read or rendered
  • 01:17:44 properly that's great but see what's
  • 01:17:47 gonna happen is if we have multiple
  • 01:17:49 notes here how much you think about this
  • 01:17:51 for a second okay
  • 01:17:52 I'll prove it in just a second but I
  • 01:17:54 want you to think about it first so
  • 01:17:56 let's say we have two notes and I select
  • 01:17:58 this note
  • 01:17:59 well component didn't mount is called
  • 01:18:01 when it first gets when that component
  • 01:18:03 first gets pushed into the Dom so when
  • 01:18:08 we click this it renders this this react
  • 01:18:10 quill component and component did mount
  • 01:18:14 is called now if we come over here and
  • 01:18:16 select a different note this component
  • 01:18:20 is already mounted component didn't
  • 01:18:21 Mountain is not going to get called
  • 01:18:22 again so how can we possibly re-up
  • 01:18:25 date our state with the new props well
  • 01:18:30 what we're gonna have to do is we're
  • 01:18:32 gonna have to use another lifecycle hook
  • 01:18:34 called this top
  • 01:18:35 I mean component did update and use an
  • 01:18:38 if statement inside of it to tell
  • 01:18:40 whether or not it is time to update the
  • 01:18:42 state or not so I want to go ahead and
  • 01:18:45 just take a second and prove this and so
  • 01:18:47 that it's not just theory so let's go
  • 01:18:49 ahead and do that now all right so I'm
  • 01:18:51 over at my firebase console and I've got
  • 01:18:53 the database table here so I'm gonna add
  • 01:18:56 a new note so I'm gonna add a document
  • 01:18:57 Auto ID and then we'll have a title and
  • 01:19:00 you know I'll just be like yo yo what's
  • 01:19:03 up and then I'll put a body here and
  • 01:19:07 I'll just put nothing much and then give
  • 01:19:11 it an ID which I actually I don't think
  • 01:19:15 the ID is supposed to be in here so I'll
  • 01:19:17 just give it a title in a body and then
  • 01:19:19 save it and that was supposed to be HTML
  • 01:19:22 let me actually update that really quick
  • 01:19:23 the the body is supposed to be HTML me
  • 01:19:27 we'll just give it a h h2 let's give it
  • 01:19:30 a ch2 give us some variants here okay so
  • 01:19:35 I'm adding this note really quick so
  • 01:19:37 when I come back over here you can see I
  • 01:19:38 have a second note because it updates
  • 01:19:40 automatically so what do you thinks
  • 01:19:42 gonna happen when I click this just as I
  • 01:19:44 explained right I'm gonna click this
  • 01:19:45 it's not calling component did mount
  • 01:19:47 again you can see that this is now the
  • 01:19:49 selected note because it's highlighted
  • 01:19:52 so it's updating state properly the
  • 01:19:54 problem is it's not updating the react
  • 01:19:56 kwill component at all and that's
  • 01:19:58 because we're calling component didn't
  • 01:19:59 mount instead of component did update
  • 01:20:01 but we have to do both okay
  • 01:20:03 so we have to do both so I just wanted
  • 01:20:05 to prove that really quick show you that
  • 01:20:07 the problem exists and why we're doing
  • 01:20:09 it this way so component did update okay
  • 01:20:12 so this react suck gets called whenever
  • 01:20:16 the component properties are updated and
  • 01:20:18 so we are gonna put an if statement in
  • 01:20:21 here that says if this dot props dot
  • 01:20:23 selected note dot ID does not equal this
  • 01:20:30 state dot ID so that means if I come
  • 01:20:34 over here and I click this one so say
  • 01:20:35 this is selected and then I come over
  • 01:20:37 here and try to select it again is
  • 01:20:39 not gonna call this function okay
  • 01:20:41 instead it's saying if the ID of the one
  • 01:20:45 that you've just selected is different
  • 01:20:48 from the one that it's displaying then
  • 01:20:50 we want to go ahead and call this again
  • 01:20:53 which is set States so I'm going to copy
  • 01:20:55 this and add some curly braces here and
  • 01:20:57 paste this in save it so now I'll select
  • 01:21:01 this note you can see it says hello
  • 01:21:03 world and then I'll come over here and
  • 01:21:04 select this note and you can see that it
  • 01:21:06 does in fact display the note as
  • 01:21:09 expected so now I can go back and forth
  • 01:21:11 between these two notes so this is great
  • 01:21:15 the only other thing we need to do
  • 01:21:16 inside of the editor component is
  • 01:21:18 implement our update function so instead
  • 01:21:22 of logging let's call this dot props dot
  • 01:21:29 note update this dot props that note
  • 01:21:33 update is that what we called it let me
  • 01:21:35 go back to the app dot J's file
  • 01:21:39 doo-doo-doo looks like we forgot to add
  • 01:21:44 that so I'm going to inside of the
  • 01:21:46 app.js file inside of the editor
  • 01:21:49 component opening tag we need to add one
  • 01:21:51 more prop and we're going to call it
  • 01:21:52 note update note update and we will set
  • 01:21:57 that equal to this dot note update which
  • 01:22:00 does not exist so I'll come down here
  • 01:22:03 and just quickly say note update is a
  • 01:22:07 function and I want to say note update
  • 01:22:10 let's see
  • 01:22:12 node update takes an ID and a note
  • 01:22:15 object okay and I just want to log those
  • 01:22:19 whenever this happens for now okay so
  • 01:22:24 back to the editor so now that we have
  • 01:22:27 this we can say this dot props that note
  • 01:22:29 update and remember it takes an ID and a
  • 01:22:32 note object so the ID is clearly going
  • 01:22:36 to be this state ID easy enough but this
  • 01:22:40 note object is going to be it's going to
  • 01:22:43 have two things it's gonna have a title
  • 01:22:45 which will simply be the state title and
  • 01:22:48 it's also going to have a body which is
  • 01:22:51 going to be
  • 01:22:52 this does States dot body okay we save
  • 01:22:57 that and so if I come over here and I
  • 01:23:02 start trying to update the note so I'd
  • 01:23:04 just be like yo I'm just typing some
  • 01:23:06 stuff in here and I stopped typing for
  • 01:23:07 1.5 seconds you can see that it does
  • 01:23:11 console.log the ID and the note object
  • 01:23:15 and body is undefined here so let's see
  • 01:23:17 why is body undefined so this state dot
  • 01:23:20 body appears to be undefined let's see
  • 01:23:23 ah so it should be text instead of body
  • 01:23:28 so this state dot text caught myself on
  • 01:23:32 that just in time so let's go back over
  • 01:23:35 here and try to update this so a type
  • 01:23:37 type type type and then I let go and you
  • 01:23:41 can see that body is what we would hope
  • 01:23:43 it would be so perfect now of course
  • 01:23:46 it's not actually updating that in the
  • 01:23:48 database yet and that's because inside
  • 01:23:49 of the app dot JS file we are simply
  • 01:23:52 logging and we're not going to firebase
  • 01:23:53 but like I said I wanted to just knock
  • 01:23:56 out this editor stuff so we could get
  • 01:23:58 back to our app to app dot J's functions
  • 01:24:01 and we can start finishing up the app's
  • 01:24:03 functionality so with that being said
  • 01:24:06 let's go ahead and head over to our app
  • 01:24:08 dot J's file and start knocking out all
  • 01:24:10 those functions that we added to the
  • 01:24:12 sidebar component and also this note
  • 01:24:15 update function here okay so what do we
  • 01:24:19 want to start with let's actually start
  • 01:24:21 with our note update function since we
  • 01:24:22 already pretty much have it ready so
  • 01:24:25 what we want to do is we want to go
  • 01:24:27 ahead and update firebase so we're gonna
  • 01:24:30 say firebase dot firestore dot
  • 01:24:34 collection and the name of our
  • 01:24:36 collection was notes dot doc and we have
  • 01:24:42 the ID already because we're passing it
  • 01:24:44 in right here so we have the ID for the
  • 01:24:46 document very convenient and we're gonna
  • 01:24:48 say update and all we have to do for
  • 01:24:52 update is pass in the object and it's
  • 01:24:56 gonna be title so if you remember if we
  • 01:24:58 go to firebase which I'm not gonna do
  • 01:24:59 but you can imagine you can look at it
  • 01:25:03 yourself if you want as well the object
  • 01:25:05 the
  • 01:25:06 object inside of the document is gonna
  • 01:25:07 have a title in a body but we also want
  • 01:25:09 to add a timestamp to it and that's so
  • 01:25:11 that if you guys want to extend this
  • 01:25:13 application anyway you can actually
  • 01:25:14 utilize that timestamp to show when it
  • 01:25:16 was last updated so we'll say the title
  • 01:25:20 is equal to note ABS dot title the body
  • 01:25:29 okay the body is equal to note Hogs dot
  • 01:25:34 body and then the timestamp is going to
  • 01:25:40 be equal to firebase that firestore dot
  • 01:25:44 field value dot server timestamp and
  • 01:25:50 this what this is gonna do is it's a
  • 01:25:52 firebase function that's going to
  • 01:25:54 generate a timestamp for us on the
  • 01:25:56 server so we don't have to worry about
  • 01:25:57 trying to create a date/time object and
  • 01:26:00 all of that it's going to handle it for
  • 01:26:01 us okay
  • 01:26:02 cool so I'm gonna save this and let's
  • 01:26:05 test this out let's go over to yo what's
  • 01:26:07 up and instead of nothing much I want to
  • 01:26:10 come over here and say hello and now you
  • 01:26:15 can see over here it actually did in
  • 01:26:17 fact update firebase because the body
  • 01:26:20 has been updated to hello inside of the
  • 01:26:22 preview as well so let's go to firebase
  • 01:26:25 and just make sure that that updated
  • 01:26:26 inside of the table so I went to my
  • 01:26:29 firebase console I'm going to database
  • 01:26:31 and then I'm going to go to that note
  • 01:26:33 and you can see now it says hello
  • 01:26:36 instead of nothing much perfect cool so
  • 01:26:42 now that we have that working we have no
  • 01:26:44 update working let's go ahead and add
  • 01:26:47 the ability to create a new note okay so
  • 01:26:52 let's go underneath note update and
  • 01:26:55 create a function called new note now
  • 01:27:00 new note is going to be asynchronous and
  • 01:27:02 it's going to accept a title
  • 01:27:04 asynchronous and is going to accept a
  • 01:27:06 title so by default the new notes body
  • 01:27:10 will be empty and it'll just have a
  • 01:27:12 title so we're gonna say Const note is
  • 01:27:15 equal to an object and inside of this
  • 01:27:18 object we will have a title
  • 01:27:19 which will be equal to title which is
  • 01:27:22 coming from right here and we will also
  • 01:27:25 have a body which we will manually empty
  • 01:27:29 string that now below the note we're
  • 01:27:32 gonna say Const note
  • 01:27:35 I'm sorry new from D B is equal to oh
  • 01:27:40 wait so we're gonna await a firebase
  • 01:27:43 call dot firestore dot collection the
  • 01:27:51 collection is notes goodness dot ad so
  • 01:27:57 we're adding we're using the add
  • 01:27:58 function which allows us to add an item
  • 01:28:00 to the collection and it's gonna have a
  • 01:28:03 title which is going to be note dot
  • 01:28:05 title it's going to have a body which is
  • 01:28:09 going to be equal to
  • 01:28:10 note note body which is just that empty
  • 01:28:13 string and then time stamp which we can
  • 01:28:16 just we can actually just go over here
  • 01:28:18 and copy what we had here so we're gonna
  • 01:28:21 create it with a time stamp here ok so
  • 01:28:24 now that's the new note from DB so what
  • 01:28:26 we're doing is we're just setting we're
  • 01:28:29 creating this in firebase and then we're
  • 01:28:31 waiting for that to respond from the
  • 01:28:35 server and then whatever the response is
  • 01:28:36 from the server we're setting that equal
  • 01:28:37 to a variable called new from DB so
  • 01:28:41 below that we want to go ahead and
  • 01:28:43 create a Const called new ID and set
  • 01:28:46 that equal to new from DB da ID so that
  • 01:28:51 we can have access to that that document
  • 01:28:54 ID that's automatically generated by
  • 01:28:56 firebase we can have access to that
  • 01:28:58 because we're gonna need access to that
  • 01:28:59 we're using that throughout the
  • 01:29:00 application as you've noticed so you
  • 01:29:03 know right here for instance we're using
  • 01:29:05 it right here you can see it all
  • 01:29:06 throughout the application right here as
  • 01:29:08 well so we need access to that so what
  • 01:29:10 we're doing is we're just grabbing that
  • 01:29:12 from the response that's why we're
  • 01:29:13 accessing that then we're gonna await
  • 01:29:16 again we're gonna await this dot set
  • 01:29:18 state because set state is actually
  • 01:29:20 asynchronous inside of react and we're
  • 01:29:22 gonna update some state here we're
  • 01:29:23 guessing notes we want to update the
  • 01:29:26 notes array and we want to use the
  • 01:29:28 spread operator to say it should be all
  • 01:29:30 of the notes we already have so this dot
  • 01:29:32 state done notes
  • 01:29:33 along with the new note which note is
  • 01:29:38 this object right here okay and let's
  • 01:29:42 see looks like yeah okay sorry about
  • 01:29:55 that
  • 01:29:56 so we're awaiting that and then we want
  • 01:29:59 to say Const new note index so we want
  • 01:30:03 to go ahead and find the index of the
  • 01:30:06 new note inside of that notes variable
  • 01:30:08 so I'm gonna say this state dot notes
  • 01:30:12 dot index of whoa
  • 01:30:15 index of and I'm gonna use so index of
  • 01:30:21 is a function of the array object that
  • 01:30:23 finds the index of a particular item
  • 01:30:26 inside of an array and so what we have
  • 01:30:28 to pass it is the actual item inside of
  • 01:30:30 the array now I'm gonna go ahead and do
  • 01:30:34 it this way this state dot notes dot
  • 01:30:38 filter okay so I'm going to filter
  • 01:30:42 through that array and I'm gonna find
  • 01:30:44 the one where the note is equal to the
  • 01:30:48 current note the note that we're on so
  • 01:30:49 we're iterating through for each note we
  • 01:30:51 want the one where note that ID is equal
  • 01:30:54 to nu ID now that's going to return an
  • 01:31:00 array because filter returns an array
  • 01:31:02 but we know for a fact it's only going
  • 01:31:04 to return one item because of this right
  • 01:31:07 here so since it's only gonna return one
  • 01:31:09 item we can just go ahead and safely
  • 01:31:10 return the zero index and know that that
  • 01:31:14 will be the one that we were looking for
  • 01:31:15 okay so let's let's look at this line
  • 01:31:17 really quick Const new note index this
  • 01:31:21 dot state notes the index of so we're
  • 01:31:23 finding the index of this one and this
  • 01:31:27 one is this state notes dot filter so
  • 01:31:29 we're going through each and we're
  • 01:31:31 iterating through the the notes and
  • 01:31:34 we're looking for the one where it's
  • 01:31:36 equal to the ID right here so we find
  • 01:31:39 the one with this ID inside of notes and
  • 01:31:41 then we are selecting that automatically
  • 01:31:44 okay hope that makes sense
  • 01:31:46 this set state we're gonna set the state
  • 01:31:49 now and we're gonna say selected note is
  • 01:31:56 equal to this state dot notes and we're
  • 01:31:59 gonna use that index that we just got
  • 01:32:00 that new note index gosh
  • 01:32:04 new note index BS code is not loving me
  • 01:32:08 today selected note index will simply be
  • 01:32:14 equal to new note index okay so why is
  • 01:32:21 it we did all this well when we create a
  • 01:32:24 new note we want to go to the firebase
  • 01:32:27 add the new note in to firebase and then
  • 01:32:30 we want to update the currently selected
  • 01:32:33 note with the one we just created now
  • 01:32:35 let's demonstrate that to see why that's
  • 01:32:37 a good thing hopefully this works so I'm
  • 01:32:41 gonna create a new note I'm gonna say
  • 01:32:42 test note I'm just gonna call it test
  • 01:32:46 note and I'm gonna click submit note
  • 01:32:47 here and you can see that it did not
  • 01:32:52 successfully add the note so inside of
  • 01:32:55 sidebar j/s 72
  • 01:32:57 it's logging something instead of
  • 01:32:59 calling a function so let's go ahead and
  • 01:33:02 let's fix that so inside of sidebar
  • 01:33:05 component on line 72 correct we are
  • 01:33:09 actually logging instead of calling the
  • 01:33:11 parent function so let's see the new
  • 01:33:15 note takes the title so all we have to
  • 01:33:17 do is say here we just have to say this
  • 01:33:19 stuff props dot new note and pass it
  • 01:33:23 this dot props dot title this dot state
  • 01:33:27 title actually this does state title so
  • 01:33:29 we want to pass in this state title to
  • 01:33:33 our app dot J's new note function and
  • 01:33:36 then once that happens we want to set
  • 01:33:38 some state really quick just to reset
  • 01:33:40 everything that we're gonna say title is
  • 01:33:43 null and adding note is going to be
  • 01:33:48 false cool so let's see what happens now
  • 01:33:51 when I come over here and try to add a
  • 01:33:54 new note call it test note submit the
  • 01:33:57 note and it creates test note and
  • 01:34:00 firebase
  • 01:34:00 and then it automatically selects it for
  • 01:34:02 us and it automatically selects it here
  • 01:34:04 too so I'm just gonna say is this
  • 01:34:07 working
  • 01:34:09 question mark wait for it to update and
  • 01:34:11 you can see it does in fact update it
  • 01:34:13 over here fantastic so this is actually
  • 01:34:17 coming along pretty well so let's move
  • 01:34:18 on I think the next thing that we're
  • 01:34:21 gonna want to do is be able to delete
  • 01:34:22 notes so what I will do is come over to
  • 01:34:26 the app.js file and let's implement our
  • 01:34:29 delete note function so under new note
  • 01:34:31 create a function called delete no
  • 01:34:34 delete note is going to take the note
  • 01:34:36 object itself and we are going to say
  • 01:34:41 Const note index note index is equal to
  • 01:34:46 this state dot notes dot index of note
  • 01:34:58 cool so now we have the note index and
  • 01:35:01 we're gonna say if this does were typing
  • 01:35:06 at an awkward angle
  • 01:35:07 okay this state dot selected note index
  • 01:35:13 if this dot state does selected note
  • 01:35:14 index is equal to note index then we'll
  • 01:35:20 say this set state whoops
  • 01:35:24 stop set state selected notes index and
  • 01:35:30 we'll set that to null and I'll explain
  • 01:35:32 why we're doing this in just a second
  • 01:35:34 and selected note we will also set to
  • 01:35:37 null and then we'll have an else
  • 01:35:40 statement here where we will actually do
  • 01:35:43 the stuff and then we'll say this dot
  • 01:35:46 state dot notes dot length if it's a
  • 01:35:50 length if that's greater than one then
  • 01:35:55 we're gonna do this and this is this dot
  • 01:35:58 select note select note we'll call
  • 01:36:04 select no if
  • 01:36:06 this select note which we have
  • 01:36:09 implemented here so it takes a note
  • 01:36:11 tenant index so this select note will go
  • 01:36:13 ahead and call that with the note and
  • 01:36:16 the index now this is where things are
  • 01:36:19 gonna get a little weird so just try to
  • 01:36:21 follow with me and I'll explain it as I
  • 01:36:23 go okay the note is going to be this
  • 01:36:29 state dot notes and then we're gonna
  • 01:36:33 access it by a index which is gonna be
  • 01:36:36 this state dot selected note index minus
  • 01:36:42 one and the reason why it's minus one is
  • 01:36:44 because now there's one less so when we
  • 01:36:47 delete a note we don't like if we're
  • 01:36:51 already if it's selected for instance if
  • 01:36:53 if we have the note selected then what
  • 01:36:57 we're doing is we're d selecting the
  • 01:36:59 note that's why we have this F statement
  • 01:37:01 here so if we have this note selected
  • 01:37:03 right here already and then I delete the
  • 01:37:05 note that's already selected we want to
  • 01:37:09 deselect that note in state because we
  • 01:37:11 don't want that to still be appearing
  • 01:37:13 over here we're gonna get server errors
  • 01:37:15 it's just not gonna work out very well
  • 01:37:16 so what's gonna happen is if you delete
  • 01:37:18 the note that you're already selected we
  • 01:37:22 want to just deselect everything and
  • 01:37:23 kind of reset the state there however if
  • 01:37:26 the note that you delete I say I have
  • 01:37:30 let's just say I have this one selected
  • 01:37:32 right here let's say oh no better yet
  • 01:37:34 let's say I have this one selected okay
  • 01:37:36 this is the third note in the list if I
  • 01:37:40 delete the first note in the list now
  • 01:37:42 there's only two notes in the list and
  • 01:37:45 if there's only two notes in the list
  • 01:37:46 and I have the third one selected then
  • 01:37:48 the third index doesn't exist anymore so
  • 01:37:51 we're gonna get errors so what we're
  • 01:37:52 doing here is we're trying to account
  • 01:37:54 for that specific problem so that's why
  • 01:37:59 this state does selected note index
  • 01:38:01 minus one okay that's why we're doing
  • 01:38:03 that so then we're gonna say the index
  • 01:38:06 is this dot state dot selected note
  • 01:38:09 index minus one so yeah so now we have
  • 01:38:11 the note which is the current note minus
  • 01:38:15 one the state notes the state dot
  • 01:38:18 selected note in
  • 01:38:19 X minus 1 and then we also have to pass
  • 01:38:22 the index because that is the second
  • 01:38:24 argument to the Select Note function
  • 01:38:26 here and that is simply the state does
  • 01:38:29 selected no index minus 1 okay go
  • 01:38:33 through that so we'll put a colon here
  • 01:38:34 since we're still inside of the ternary
  • 01:38:36 operator and you know else if this dot
  • 01:38:41 state dot notes dot length is not
  • 01:38:44 greater than 1 well what that means is
  • 01:38:48 we have no more notes so let's go ahead
  • 01:38:50 and basically just copy this just copy
  • 01:38:56 this line right here let's deselect
  • 01:38:59 everything so if we only have one note
  • 01:39:02 in this list and we delete it there's no
  • 01:39:05 more notes so we need to just deselect
  • 01:39:06 everything all right cool alright so now
  • 01:39:11 that we got all that taken care of we
  • 01:39:12 can go ahead go to firebase and delete
  • 01:39:15 our note so we'll say firebase dot fire
  • 01:39:18 store
  • 01:39:19 dot collection I think you guys are
  • 01:39:21 getting used to this part pretty quick
  • 01:39:23 notes is the name of the collection dot
  • 01:39:25 doc we have the the ID I believe let me
  • 01:39:30 just quickly yeah note that ID node ID
  • 01:39:35 and then we will do dot delete which
  • 01:39:39 makes it really easy for us to delete it
  • 01:39:42 it's built in to firebase so all right
  • 01:39:44 so I'll save that but I'm not gonna
  • 01:39:46 click delete yet because we still have
  • 01:39:48 to go if we look at our sidebar item we
  • 01:39:51 are in fact calling the delete note and
  • 01:39:54 we're passing note as the parameter here
  • 01:39:56 but in sidebar we're only logging still
  • 01:39:59 so we need to save this stuff props dot
  • 01:40:03 delete note we need to pass the note so
  • 01:40:07 we'll accept note as the argument here
  • 01:40:09 and I think that's gonna do it for us
  • 01:40:13 for deleting notes so let's test it out
  • 01:40:16 let's say I select this note and then
  • 01:40:19 let's say I delete the note that I have
  • 01:40:20 selected here let's see what happens
  • 01:40:22 when I when I do this cool so I had a
  • 01:40:24 note selected I deleted the one that I
  • 01:40:26 had selected and now nothing is selected
  • 01:40:28 that's perfect that's exactly what we
  • 01:40:30 wanted to happen
  • 01:40:31 now let's select this note and delete
  • 01:40:34 the one underneath it and see if this
  • 01:40:36 one stays selected let's see what
  • 01:40:39 happens it sort of worked but it also
  • 01:40:42 didn't because this is selected here but
  • 01:40:47 our react quill component broke when
  • 01:40:49 that happened so it's our state is
  • 01:40:51 correct but we have to fix something in
  • 01:40:53 our react quill component for this to
  • 01:40:55 work properly okay so after a little
  • 01:40:58 experimenting I believe I found the
  • 01:41:00 problem that we had with where we were
  • 01:41:02 getting that error and the reason why we
  • 01:41:04 were getting that error I believe is
  • 01:41:06 because we are not removing the so let
  • 01:41:12 me get rid of this sorry so we were not
  • 01:41:16 removing the note that we're deleting
  • 01:41:19 from the notes state at all so we need
  • 01:41:26 to do that so what we need to say is
  • 01:41:29 underneath here we'll just go ahead and
  • 01:41:31 do that really quick actually I will
  • 01:41:33 make this asynchronous so I'll say async
  • 01:41:35 and then I will say here underneath the
  • 01:41:38 note index I will await this not set
  • 01:41:40 state and I'm going to set the whoops at
  • 01:41:44 the notes estate notes equal to notes
  • 01:41:49 dot filter and we just want to return
  • 01:41:51 all of the notes except for the note
  • 01:41:53 that we're passing in right here so
  • 01:41:55 we're just gonna say note stuff filter
  • 01:41:57 and for each note we want every single
  • 01:42:00 know where a note doesn't where note
  • 01:42:02 does not equal note and let's see if
  • 01:42:07 that fixes our problem here notes is not
  • 01:42:09 defined line 87 and that's supposed to
  • 01:42:13 be this wait see this is we this does
  • 01:42:18 state this does state dot notes cool all
  • 01:42:22 right let's see if this fixes our
  • 01:42:23 problem so I'll select this note and
  • 01:42:25 then I'll delete the one before it and
  • 01:42:27 we do not get the error that's that's
  • 01:42:30 actually great so that makes some of
  • 01:42:32 this code a little bit
  • 01:42:36 I guess pointless because what we were
  • 01:42:38 trying to do is if I come back in here
  • 01:42:40 and select this note what I was trying
  • 01:42:42 to be able to do is have this note
  • 01:42:44 selected
  • 01:42:45 and then if I were to delete this note I
  • 01:42:47 would want this note to stay selected so
  • 01:42:52 if I come back up here delete it you can
  • 01:42:54 see that it's no longer selected anymore
  • 01:42:56 and that's perfectly fine the reason why
  • 01:42:57 that's happening is because we're
  • 01:43:00 changing the work we're updating the
  • 01:43:02 state beforehand before this if
  • 01:43:04 statement but what I want you guys to do
  • 01:43:08 since this is an intermediate level
  • 01:43:10 tutorial I want you guys to figure out
  • 01:43:13 how to fix that problem and you can
  • 01:43:16 clone the repository and figure out how
  • 01:43:18 to fix it and then you know if you want
  • 01:43:20 to post in the comments that you fixed
  • 01:43:22 it and share with others how you fixed
  • 01:43:23 it absolutely please do that but I'm not
  • 01:43:26 gonna fix that in this tutorial I do I
  • 01:43:28 did want to lead you leave you guys with
  • 01:43:30 a little bit of homework and I think
  • 01:43:31 this problem is going to be perfect for
  • 01:43:33 you guys so I'm gonna leave you with
  • 01:43:35 that I'm also going to leave you with a
  • 01:43:36 little bit of extra homework afterwards
  • 01:43:38 as well so let's go ahead and move on to
  • 01:43:42 the next function this is actually going
  • 01:43:45 to be inside of our editor component
  • 01:43:47 which we do not have the ability yet to
  • 01:43:51 update our titles so we need to do that
  • 01:43:54 so what we will do is inside of the
  • 01:43:57 render let's go ahead and add a few more
  • 01:43:58 elements to our return inside of our
  • 01:44:02 editor J's file so let's quickly come up
  • 01:44:06 to the top of our editor container here
  • 01:44:08 and let's create a border color icon and
  • 01:44:15 inside of the opening tag we'll give it
  • 01:44:18 a class name that we will set equal to
  • 01:44:20 classes dot edit icon whoops all right
  • 01:44:25 so we have the Edit icon and below this
  • 01:44:28 will create an input and inside of the
  • 01:44:32 opening tag will add some props here or
  • 01:44:35 not really props since this is a
  • 01:44:37 standard HTML element but you get what
  • 01:44:42 I'm saying so class name classes dot
  • 01:44:45 title input and then underneath that
  • 01:44:49 we'll have a placeholder which will be a
  • 01:44:52 plain string and we'll say note title
  • 01:44:55 Dada
  • 01:44:57 of value which will be this state title
  • 01:45:04 whoops this state title so if this DA
  • 01:45:07 state title exists we'll use the turn
  • 01:45:09 ternary operator then we'll go ahead and
  • 01:45:12 say this state title otherwise we'll
  • 01:45:16 just do an empty string and then we'll
  • 01:45:20 have a non change function on change and
  • 01:45:23 the on change will
  • 01:45:25 oops automatically get past the event
  • 01:45:28 which we will pass to our own function
  • 01:45:30 called this to update title this update
  • 01:45:33 title and we will pass a target value to
  • 01:45:41 that and underneath update body we'll go
  • 01:45:43 ahead and create our Update title
  • 01:45:44 function so update title you can see
  • 01:45:47 we're passing the text in so txt and for
  • 01:45:53 update title what we want to do is we
  • 01:45:55 basically want to do exactly what we did
  • 01:45:57 with update body so let's say a weight
  • 01:46:01 let's go ahead and add a sink here oops
  • 01:46:05 oh my gosh okay a sink we want to update
  • 01:46:11 we want to await this dot set state the
  • 01:46:15 chunk of state that we are updating is
  • 01:46:17 the title so it'll be title and we'll
  • 01:46:20 set that equal to txt and once that gets
  • 01:46:22 done we will call this top update so it
  • 01:46:26 will also have a D bounce effect as well
  • 01:46:29 so let's see what happens if I come over
  • 01:46:31 here let me just make this a little
  • 01:46:34 smaller make this a little bigger okay
  • 01:46:36 you can see there's this input here now
  • 01:46:38 when I come in here I can highlight it
  • 01:46:40 and instead of two I'll put like two two
  • 01:46:43 two and you can see it updates the title
  • 01:46:47 as we were expecting expecting it to so
  • 01:46:50 let's go through and test everything so
  • 01:46:53 let's create a new note I'm going to
  • 01:46:54 call this test Note one just for the
  • 01:46:58 heck of it I submit the note it's
  • 01:47:00 automatically selected here you can see
  • 01:47:02 I have a typo so I'm going to fix that I
  • 01:47:04 go in here to edit my note title and it
  • 01:47:07 correctly edits the note title
  • 01:47:09 in here add some text and say hello this
  • 01:47:12 is working and then you can see it
  • 01:47:15 updates here I'll click this note it now
  • 01:47:17 selects this note let's say I don't want
  • 01:47:19 all three twos here I just want to put
  • 01:47:21 this as a test hit updates here I can
  • 01:47:25 come back over here and let's just say
  • 01:47:27 you know replace this with text that
  • 01:47:30 make sense
  • 01:47:31 testing the body cool so that updates
  • 01:47:35 and now I'm going to delete this note so
  • 01:47:38 I delete it it deselects everything I
  • 01:47:40 delete this note now we have no notes
  • 01:47:42 and the app appears to be working
  • 01:47:45 perfectly so final note test yep it's
  • 01:47:52 all working as expected so this is a
  • 01:47:55 fully functional Evernote clone
  • 01:47:57 application where you can take your own
  • 01:47:59 notes and everything and as you remember
  • 01:48:01 there was a a small thing that you guys
  • 01:48:04 could fix on your own if you'd like to
  • 01:48:07 which is the selecting so if I have
  • 01:48:10 multiple notes and I delete one of the
  • 01:48:12 notes keep the one that's selected
  • 01:48:13 selected instead of deselecting it you
  • 01:48:16 know explicitly please try to fix that
  • 01:48:19 if you are interested in furthering your
  • 01:48:22 abilities within react that would be a
  • 01:48:24 great exercise for you another great
  • 01:48:27 exercise for you is to go watch the
  • 01:48:30 other tutorial that I have in the
  • 01:48:31 description which is for an instant
  • 01:48:34 messaging application in which it goes
  • 01:48:35 over how to create user accounts so
  • 01:48:38 you'll be able to create user accounts
  • 01:48:39 and then what I think would be
  • 01:48:42 interesting is for you to take this
  • 01:48:44 Evernote application and create user
  • 01:48:48 accounts so that a user can sign in and
  • 01:48:51 they can have their own notes and then
  • 01:48:52 another user can sign in and they won't
  • 01:48:54 have access to any other notes but their
  • 01:48:56 own so its user based so I highly
  • 01:48:59 recommend you try watching that tutorial
  • 01:49:01 and then afterwards come back to this
  • 01:49:04 tutorial when you're done with it and
  • 01:49:07 try to combine what you learned in the
  • 01:49:10 previous tutorial and in this tutorial
  • 01:49:12 and see if you can add the ability to
  • 01:49:14 have users with this Evernote clone
  • 01:49:19 alright guys I really hope you enjoyed
  • 01:49:21 this tutorial and
  • 01:49:23 know that it went pretty quickly and I
  • 01:49:24 know that it was probably a little bit
  • 01:49:26 confusing but there are certain parts
  • 01:49:28 where it's good that it's confusing if
  • 01:49:30 that makes sense it's a little
  • 01:49:31 challenging and you can stop you can
  • 01:49:33 pause and you can think deeply about
  • 01:49:35 these topics and when you do get it it's
  • 01:49:37 you get a good sense of satisfaction
  • 01:49:38 that you learned something new so I
  • 01:49:41 really hope you did enjoy if you did
  • 01:49:43 please give me a like subscribe to my
  • 01:49:45 channel and I will see you guys in the
  • 01:49:47 next tutorial