There we can do something similar.
We can create separate functions
for connecting and inserting
and since we would be reusing the same logic,
we might wanna go for some helper functions instead.
We got that helpers folder anyways
with some API utilities
and there we can add a db-util.js file
to set up our database utility functions.
And I'll then go to the newsletter.js file
and grab the connectDatabase and insertDocument functions,
cut them from newsletter.js
and instead add them in db-util
and just change the insertDocument function
such that it also takes the collection as a parameter
so that we don't always talk
to the newsletter collection here
but to any collection we get as a parameter.
Now we wanna export both functions
so that we can import them into our files
and then we can use them here in newsletter.js.
There we can now import from our db-util file
by going up to the helpers/db-util
and here I'll import connectDatabase and insertDocument
and for insertDocument, we now just also need
to pass in that collection name
as a second argument so that the email is inserted
into the correct collection.
And with that, we can go to the eventId file here
and also import these two functions here.
So from the helpers folder.
We wanna import from the db-util file
and here we also wanna import connectDatabase
and insertDocument and then use that.
Here, for example, we connect to the database,
so here we wanna await connectDatabase like this
to get access to the client.
Now, this could be failing,
so just as before,
I will wrap it in a try catch block.
Catch any error we might be getting like that
and create client as a variable,
which we then set in here.
And then in here, we wanna send back a response
with a status code of 500
and some message in the JSON body
that could be connecting to the database failed.
Like this, and then still return
to avoid that the rest of this function executes.
If we do connect successfully down here,
we're inserting the comment,
we don't wanna run this code here.
Instead we wanna execute insertDocument,
pass the client to insertDocument,
use the comments collection
and pass the newComment as a document
that should be inserted.
And await to get access to the result.
And for that, we wanna make sure that in db-util,
we actually do return that result
so that here we also grab that result
and return it like that.
With that, we can insert the document
and still use the result to then update the ID.
Here we, by the way, also might wanna use _id
to be in line with the automatically generated field
because there the field name is also _id
as you saw in the last lectures.
Now, the main goal was to add error handling though
and hence, I'll wrap this into a try catch block as well.
Catch any potential errors,
return to not execute any other code if that did fail
and then send back a status code of 500
and some response data
where we again could add a message
of Inserting comment failed.
And now I just want to create result as a variable,
which I actually set here to get scoping right.
Now the only remaining part is where we get our data.
We can also create a helper function for that
even though we only use it here
but still to have a uniform approach
when it comes to working with the database.
I will go to the db-util file
and export another async function.
getAllDocuments sounds like a fitting name.
And here I also need the client
and the collection from which I wanna get all documents.
And then we can take this code
where we get access to the database
and then fetch all entries and comments
and paste that into getAllDocuments.
Now actually we might wanna accept sort,
this sort object as a argument as well
to make this function more flexible
and let the caller of the function specify how documents
should be sorted.
Then we wanna use collection here
and use the sort parameter here
and ultimately, of course, return our documents.
Like this.
Now in the eventId file,
we can import this newly added getAllDocuments function
from the db-util file and use it down there.
Here in the GET case, I wanna call getAllDocuments,
pass in my client, pass in my collection name,
which is comments
and pass in my sort object,
which defines that I wanna sort by id in descending order.
Then we can remove this
and await getAllDocuments
to get all our documents here like this
and return our response.
But again, we wanna add error handling
so we can try this and catch any errors
if something goes wrong here.
In which case, we stop function execution with return
and then return a different response
where the status code is set to 500
and we pass on some message.
For example, here we could say Getting comments failed.
Now, you will be able to refactor more.
For example, sending back that error response
is always pretty much the same.
You could also create a separate function for that,
just as a side note.
Now, with that, we get our documents here
and I wanna send back a response here if that all works,
otherwise we send back that error response.
And we then close the client
and actually now that I move to this success response
into the try block, we can remove this return statement
to make sure that we do close the client
if we make it past try catch here.
So to make sure that we do always get rid of that connection
once we're done with our operations.
And actually, I wanna do something similar here
for inserting a comment.
Move this success code into the try block
and then don't return here
so that we still do reach this part at the bottom eventually
where we do close the connection.
That's why I like this way of handling it better.
I also wanna close the connection here
if we have invalid input.
So I'll copy client.close
and add it in here
because here I then wanna return.
I don't wanna continue with code execution.
Hence here, I wanna close the client,
so close the connection.
And here we don't wanna close the connection
because here establishing the connection failed already.
So here we definitely wanna return.
And with all of that,
we can again test this.
Again by breaking our credentials.
Then go to a single event.
And show the comments.
And fetching them fails now.
And this breaks the front end application actually
because now we're trying to map through all comments,
even though we got no comments.
So we might wanna add better error handling
on the front end as well.
For the moment, I'll just fix it
by bringing back my credentials and reloading.
Now this still fails.
So it seems like something is wrong.
Now let's see what's wrong by reloading
with the Network tab open
and then if I click on Show Comments,
this request still fails,
connecting to the database failed here
even though I've fixed my credentials again.
Even though I did that,
it looks like calling connectDatabase failed
in my handler function here.
And actually, I know what went wrong.
I moved my function here,
my helper functions here into the db-util file
but there I'm referring MongoClient.
We need to add that import.
So we should grab that MongoClient import
and remove it from the newsletter file.
We don't need it there anymore.
Same is true for the eventId file
in the comments folder.
We can get rid of it there
but we should add this import in the db-util.js file
because we are using MongoClient there.
That's why connecting failed.
I was referring to MongoClient
without having it available.
So now with that, if we now reload,
loading the comments works
and if I now break my credentials here and save this,
if I now try to submit
a new comment,
this should fail and it does.
So that works.
Again, no feedback on the front end.
We could add it, we don't have it here.
If I bring back my correct credentials
and I try the same data again, this now worked.
If I now hide the comments and show them again,
we see that both comments are loaded as well.
So that is all working here
and we now did also add error handling therefore.