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