All right.
And once we have a clear understanding how we can set up our own custom validation, let's kick it up
a notch and let's make it more complex.
And in the process, we will clean out our controllers even more.
So what am I talking about?
Well, let's navigate to a job controller first and notice how in all of the routes where we're looking
for that ID parameter, we're also checking whether the actual job exists.
And essentially, we can just move this functionality again to our custom validate function.
And effectively, we'll not only say a few lines of code, but we'll have that functionality in one
place.
So let's try it out.
First, what we need to understand is that in order for this functionality to work, our custom function
is going to be async.
Now, why is that so important?
Because remember, with asynchronous functions, they return a promise.
So essentially, if you have a functionality that's synchronous, yes, this is going to be the approach
you're going to take.
You'll either return true or false, but if you want to set up a synchronous functionality, then the
approach is going to be a little bit different.
Basically, we will right away need to throw the errors.
So what am I talking about?
Well, first of all, let's make this async since we will work with the database to check whether a
job exists, then I want to actually wrap this into a curly bracket.
So instead of implicit return, something we used in the previous video, now we'll go with explicit
return and we'll throw our own errors instead of returning.
True or false, since at the moment custom is already async, we need to use this different approach
First, let's just make sure that our is valid works and I'm going to start by creating a new variable.
I'm just going to say is valid ID.
And that one is going to be equal to this functionality.
So let me cut it out.
Let's set it up over here.
Now, this one is either true or false.
So that, of course, doesn't change what we're getting back from This is valid.
But now we want to set up a condition right here in our custom one, and we're going to go is valid
ID.
And then if is valid, is false.
Essentially, if it's not a valid ID, we want to throw new.
And again, we're looking for our own custom request.
Let's take a look.
Yep.
We imported everything is fine and then we just need to provide the value and that one is going to be
the same.
So we're not going to use this message anymore.
So essentially we're throwing our own errors.
And again, we need to do that because async function is not going to return true or false?
So we kind of need to do this manually, I should say.
So let me take this out.
So I'll use the same message.
So that's the is valid one.
And I don't think there's a need to test it one more time.
So this will be testing our job one anyway.
All right.
So again, we can successfully check for valid MongoDB, but how we can check whether the job exists
in our database?
Well, let's navigate back to job controller and let's take a look at get job.
So in order to get the specific job, here's what we do.
We go here with weight, then job find by ID.
We pass in the ID, and if it doesn't exist, well, then we throw the error.
Correct.
So this one will stay the same in the get job.
But once we have the validation in place, we'll be able to remove the errors.
So let's try it out over here.
First, I'm just going to copy these two lines of code.
Sorry, I don't want to cut it out.
We're just going to copy.
Let's navigate back over here.
Let's paste it.
We don't have the job model, so that's the first thing we want to import.
So I'm going to go here with import job from and then let's go.
One level up.
We're looking for models and more specifically, a job model.
Now, we also want to change some code around here.
Notice this is an ID.
Well, at the moment ID is actually in the value parameter, so we're still looking for the specific
job.
And if the job doesn't exist, we want to get the not found error.
So of course we also want to import the not found custom error.
And we want to change this one to a value.
So let's navigate up and grab that not found error.
So right after the bad request one, I also want to get the not found.
Let's save and we're going to navigate back to a job controller and one by one, let's remove some lines
of code from the controllers so this one stays the same.
We're still grabbing the correct job and all that.
Then when it comes to the update job, we don't need this line of code anymore.
So this one we won't use.
And also same goes for remove job.
So now essentially we know that by the time we get to the controller.
Everything should be correct.
If the job doesn't exist in our database, then the validation layer is already going to check it and
essentially send back the error response so we can move up over here and actually remove this import
as well.
And again, our main goal is to keep our controllers as lean as possible.
And now let's navigate to get single job.
Let's test it out.
So now we have this invalid MongoDB so that one still works.
Let me make sure that.
I have some kind of value over here, and I think I lost it, so.
Let me take this one.
Where we have get single job.
Let's send.
So if the ID is correct, then of course we get the proper one.
We already tested the invalid one.
So now let's just change around and actually keep the syntax but provide the wrong value.
And technically everything works.
We get the message, but notice the status code.
Essentially we're getting back 400.
Why?
Well, because if we take a look at our validation middleware, we'll see that for pretty much all of
the errors we are throwing 400, which is the case for the most part.
But in this case, since we're looking for specific job, we actually want to go with 404 and therefore
we'll need to do a bit more acrobatics over here.
So we're only going to run this functionality if we have some errors.
And essentially the way I'm going to check it, I'm going to look for the first item in this array that
I'm getting back, and I'm just going to make sure that it starts with no job.
Because remember, when it comes to a message over here, I go with no job.
And.
Rest of the stuff.
So if that's the case, I'll actually throw not found error.
So let's go here and let's type error messages.
We know that we're going to get back an array and we're just looking for the first item since in this
case they're not going to be multiple messages.
There's only going to be one.
So let's go with start with.
That's the JavaScript string method and I'm just going to go with no job.
So if that's the case, we want to throw.
Another error.
And this is going to be equal to not found error.
And essentially, let's pass in the same error messages.
So now let's try it out where we have single job.
Again, I'm keeping all of this the same.
Let's send and now we actually have 404 and with this in place, we have the setup to not only check
whether the MongoDB ID is valid, but also we right away check whether the job actually exists in our
database.
And before I let you go, I want to mention two more things.
First, we can refactor our controllers even more.
So when we look at the get job update job as well as delete job, we can see that we always start by
destructuring that ID, But if you want to save on some lines of code, of course you can simply go
here with req, dot params dot and then the id.
So of course in that case we don't need this line of code anymore so we can simplify and shorten our
controllers even more.
Of course we just need to repeat the same deal for rest of them.
So in this case I'll just copy and paste because it's going to be faster.
So let's grab it over here.
We don't need params anymore.
Let's remove.
And the same goes.
For deleting the job.
We don't want to destructure it again.
This is totally a preference.
I actually prefer to destructure it, but I definitely want to showcase this.
And lastly, just remember that technically in here we can throw a straight up JavaScript error because
again, we're setting up those custom errors actually in the.
With validation errors.
So here I'm just checking for no job and then I go with not found error.
So you can change these ones, both of them to a straight up JavaScript error and everything is still
going to work.
So it doesn't really matter whether we go here with our own custom error class or we go with the JavaScript
one, because at the end of the day this is where we actually set up that error class.
Now in my case I will still leave the custom ones in both places, but definitely wanted to mention
that.
And with this in place, we're ready to move on to the next topic.