now that we've got our super awesome API over here returning an empty array we
need to hook up our super awesome front-end so let's do that let's go back
over to VS Code and we're in the heroes final now so if you remember the server
file contains all of the Express stuff and the source folder contains all the
react stuff and the heroes component is the component where all the logic is
being done now down here in the heroes component the first theme that the
component does when it mounts this is fetch the heroes from the database which
is what we want but we're also going to have deletes updates creates and if we
put all of our fetch logic in this file it's gonna get kind of hairy so let's
create a different file in which we can do that I'm gonna come over here and
create a new file and just call it api.js and then inside of that let's create
first of all an API base so we'll just you know it's just slash API
it's not that complex but if it changed we can change it here without changing
everything else in the file and actually let's call it base API that looks
cleaner and then we have our hero's API which is what we're ultimately going to
return and inside of that we have a get write and then we have a create and I
bet you can guess the other two we have an update yes and the destroy yes ok so
let's go ahead and move that fetch into our get here so here's our fetch but we
do have a little bit of an issue and that issue is that it's impossible for
us to know when this thing gets done because fetch happens asynchronously and
then we get a callback which contains the result which we returned to Jason
which also happens asynchronously which then gives us the jason so in order for
us to know exactly when we've got the jason and returned at that exact point
from this method we need our own promise so we'll just do a new promise here and
then move all of our fetch inside of that there we go it's a lot better and
then let's move this down here to make this a little bit cleaner I like that a
lot better instead of calling this Jason here instead of saying this.setState
we're gonna pull this out we're gonna say resolve JSON okay so we're gonna
resolve our promise and send JSON result back up
as the result from this method and then let's add a catch we want to be clean
with our errors here if we get an error we'll just reject it like this so that
allow us to handle the error in our promise go ahead and save that
okay let's actually use this file and our heroes come up here and we'll say
heroes API oops and that is a clear line that I forgot to export default heroes
API okay now it should work heroes API there it is alright so we're importing
it let's use it down here pull out our fetch will say Heroes API yet right that
contains our promise which is going to contain our JSON
so that's how that
works and then inside of that we can set the state so we've basically abstracted
our fetch into an api file made it cleaner here let's see if we broke
anything alright we're still working the fetch is
still running we don't have any heroes yet the next thing we want to do is wire
up the Save button here so let's put our save method in so back in the API will
put our create in I'm just gonna copy it in and then we'll talk about it the
create method is gonna take in a hero object and of course we're gonna wrap in
two promise so we know when it returns and then we're gonna call fetch but
we're putting the verb to put and this should actually be post that's wrong
posts are used for create puts are used for updates and then what we're gonna do
is stringify our hero we're gonna send it across the wire as a string of text
using JSON to parse it into a string and then the server's gonna parse it
back out and we have to add these headers here in order for Express to be
able to accept our post body i see a lot of people get stuck here with Express on
sending posts and the reason is because express wants JSON in the body and we
do is specify that in the header and then the result same thing we're gonna
get a result we're gonna put it to jason we're gonna resolve the promise send the
JSON back and or reject the air the same exact thing that we did up here on
the get so let's add in the update while we're here i'm going to go ahead and
pull this out create some space for us here and i'll copy it in and the update
looks really similar except instead of a post we're gonna do a put same really
exact code as the create except with a put instead of a post our
handle save method is going to get kind of complex and the reason is because the
save method handles both the create and the update so we have to handle both of
those things in this one method so let's start by getting a reference to the
hero's object that we have in the state because we're gonna have to manipulate
that add things to it and we don't want to do that directly on the state so
we'll pull that off and then we just need to look and say are we adding a
hero so we have a boolean for that adding hero tells us that we are if we
are then we want to do a create if we're not then yep that's right we're gonna do
the update so let's do the create first we can look at our hero's API and say
create and that is going to take in a hero well the hero that we're always
modifying in our application is this dot state dot selected hero always always
always that hero that's the object that we're currently working with now once we
call the create that's gonna return a promise which is going to have a hero in
it so remember our API returns us a hero on a successful update and then we can
just do hero's dot push and we can actually just push in this dot state dot
selected hero all right that's the here it's the same hero that
we're getting back here so we can go ahead and push that one in or we could
just push in hero like this both of those would work and then we need to set
the state so let's do this dot set state and inside the state we want to set our
heroes equal to heroes which we just modified we want to say that adding hero
is false because we're not adding a hero anymore and we want us to set our
selected hero to null because we're no longer working with any specific
selected hero the operation is over so that will handle the create let's now
look at the update the updates were really straightforward it's just
heroesAPI.update and we're gonna pass in this.state.selectedHero
that's right and that's gonna return a promise which
we don't even really need to do anything with because we're just updating and if
the promise comes back successfully then we know our update was successful and
then we're just going to this dot set state and we're gonna reset our selected
hero so we'll say selected hero is no that's it that's the update and the
create so let's jump over to the app and try these out soupy mess anything up so
let's click add a new hero here we'll give it an ID we'll say let's use
Darkwing Duck anybody remember that show great one I have no idea what Darkwing
Duck saying is let's just say it's quack and then click Save and boom we're in
the database right so I can refresh we're persisted through so the create at
least is working now let's try the update click on it and now we can't edit
the ID anymore but we could say darkwing duck and maybe he says quack quack with
an exclamation mark let's click Save on that and boom let's refresh and it's
persisted through so the last thing we need to do is wire up our delete and
we're pretty much done here so let's do that let's go back to our API file here
and for the sake of expediency I'm gonna copy in our destroy method which I
misspelled anyway so this is our destroy nothing you haven't seen before a
promise a fetch a method responding turning that to JSON JSON resolving
the promise catching the air same thing we've done on the other methods and oops
let's save that and then we'll come over to heroes and we have a delete method
which I don't believe we've even implemented yet so interestingly enough
let's put that in let's do this dot handle delete equals this dot handle
delete bind because we always have to do that
and then we need to pass this down over here on our each hero element has a
delete button so what we want to do is hero say here say on delete equals this
dot handle delete perfect and then let's go into our hero component here and just
make sure that we are bound to the right thing and in this button we need to bind
the on click event so that something happens so we'll say on click equals and
props and actually we're gonna pass in a function here so we can pass in our hero
the same thing we did here right here we do the same thing so we're gonna have
props dot on delete right and then we're gonna pass in props that hero
just close it out here okay so we've implemented our delete button on the on
click method which is going to go back up here and it's gonna call our on
delete method so let's add the handle delete and they'll delete we're just
gonna receive a hero and then we can do is call our hero's API dot destroy okay
and destroy takes the hero that we want to destroy this one and then when we
successfully return from that promise we can just go ahead and remove this hero
from the collection of heroes that's in the state and that looks like this
what we're gonna do here is get a reference to our hero's collection from
the state filter over that and find the hero inside of this collection that
matches the hero that we're trying to delete so that we can then pull it out
of the collection so that's what this filter does it returns all of the items
that don't match this hero which then gives us a collection of all of the
items without this hero because that's the one we deleted and then again we set
the state because we can't we can't modify the state directly we have to
modify this object and then set it and then we've just looking to say if this
currently selected hero is equal to the hero that we just deleted then set our
selected hero back to null in other words if the Edit form was open and we
were about to update but we deleted it instead then go ahead and close the
update form because that hero no longer exists so let's save this and go back to
our app and see if that works all right so let's test out our delete
let's click delete and that works but then we got this weirdness here what
happened there exactly well interestingly enough let me add this
hero back so I can explain this when you click this button here there is actually
another event that fires down here okay and the event gets propagated so it
propagates from the button down to down to this this right here or up and so
what's happening is we're clicking delete but then it's firing off the
select event which then shows the form which gets the whole app state out of
whack so what we need to do is stop event propagation I'm gonna show you how
to do that over here in our heroes file in the handle delete we want to take in
any vent and a hero and by default we can pass
into these methods these click these bound methods and react the actual
method event or the the element event so you pass an e here this is the event and
now we're passing that in and now we can just stop event propagation so we could
say event stop propagation okay and this is the event that stops the event from
propagating from the delete button to the actual hero element itself which
then inadvertently has a side effect of firing this select which we do not want
so let's come back over to the app refresh make sure we got the latest copy
and then we'll just hit delete and you'll see that we no longer get that
edit form popping open which is ultimately what we want so now the
delete is working in subsequent episodes we're gonna look at how we can replicate
cosmos DB and keep our application fast no matter where our users are because
that's really the strength of using Cosmos DB over any other NoSQL
solution it's kind of amazing so we'll do that next I'll see you then