00:06
Just like we did with our string filter here, we want to add in an additional filter option within our app filters folder. So, new file on that.
00:14
And we'll call this file number_filter.ts. Just as we did with our string filter, we'll start with our roles.
00:20
So, we'll do number filter equals vine and import vine there using tab. And we're going to set this to a union. And this one's going to be a little bit more straightforward.
00:29
So, again, we're going to have a vine union if with a condition check for our value.
00:35
If the value is an array, so we can use array is array to check that.
00:40
Then we want to apply the validation rule vine array where each array member should be a number. So, we'll do vine number passed into vine array there.
00:50
If the value passed in is not an array, then we want to do vine union dot else. And assert that the values type should be a straight number. That is optional.
01:00
So, it can also be undefined. So, we're either going to get back an array of numbers or just a single number here for our number filter.
01:08
Just as we did with our string filter, let's go ahead and package this into a class called number_filter. And let's do our static get for our rule.
01:17
And we'll return back our number filter. And then we'll have our static build method.
01:22
Again, we need our generic of type T that extends a lucid model type from AdonisJS lucid types model.
01:30
And we want to accept in the query builder of type model query builder contract passing our T generic into it.
01:38
And then we want to accept in the column name for our where statement of type string. And the filter value that we can infer from our validation rule.
01:47
So, type of number filter for that. And if we check the type for our filter here, it should either be number, number array, or undefined. Perfect.
01:57
For our build to actually apply these in, again, let's just eliminate undefined out of the equation by doing a conditional to check and see if we don't have a filter value.
02:06
And if we don't, then we just return back. Otherwise, we can check to see if the type of our filter equals a number.
02:12
Then we go ahead and return query.where our column name equals the filter number passed in. And then lastly, that leaves our array of numbers.
02:22
So, we can do query. and rather than doing a where, we can do a where in that accepts as the first argument, the column that we want to provide the in statement against.
02:31
So, that would be our column name still. And then the array of values that we want to check against, which would again be our filter.
02:40
So, this one will accept in just a set value. So, maybe something like four. And this one will accept in an array of values that might be something like three or four.
02:50
For this one, we'll get back courses that have a status ID, difficulty ID, whatever that column name is, value of just four.
02:59
For this one, we'll get back status ID, difficulty ID, again, whatever that column name is, that match either three or four.
03:06
This union rule matches this one, and this union rule matches this one.
03:11
Since this is optional, we are also supporting that via our if not filter value return statement there as well.
03:19
All right, let's give that a save and apply these to, let's start with our validation rules.
03:25
So, we have our status ID, difficulty and access level IDs that all need to use our number filter and its rule.
03:31
So, we can apply that in there and replace all three of those with our number filter rule. All right, that looks good.
03:37
Let's give that a save, jump back over now into our search courses action so that we can apply these into our apply filter function.
03:45
So, it's going to look relatively similar to our string filter here.
03:48
We just need to do number filter dot build, pass the query in, search for, let's do our status ID first, filters dot status ID.
03:58
Then we'll have number filter build query difficulty ID, and we can do filters dot difficulty ID there.
04:07
And lastly, we have our access level. So, query access level ID, filters dot access level ID.
04:15
And now that we have those applied, we can get rid of all three of those ifs, give it a save, and let's jump back over into Hopscotch. Again, let's just test to make sure that nothing works here.
04:25
So, we're A-OK there. Next, let's try with a status ID of two, send that off. And it looks like I got a typo there.
04:34
We got a C instead of an S on status ID. So, let's go find where I accidentally did that. Right here. All right, cool. First spot we looked. Got that updated. Let's try that one more time. Okay, cool. There we go.
04:43
We get back one result now with a status ID of two, which is my first course. Switch that to three, and we get back 12.
04:50
So, if we do an array with two and three, we should get back 13, which we do indeed.
04:57
If we switch this to an array with just one value, that should behave the exact same as just providing that value straight, giving us back just one. So, awesome.
05:04
Now, we go through and test all of the combinations of all three, our status ID, difficulty, and status ID. But since they all behave and are applied similarly, I'm going to go ahead and assume that we are A-OK there.
05:14
What if we apply an ID that does not exist? So, I'm going to do just 10,000 there. Pretty much certain that that does not exist. We get back an empty array.
05:22
Again, not a validation error because we are not asserting that these actually exist inside of our database. What if we return back a string as our status ID?
05:31
For that, it's treating it as undefined because it's an empty string. If we add a test value into that, though, we get back our validation error that it must be number.
05:40
If for any reason, and this applies to the string one as well, you want this validation rule to say anything different than this,
05:46
maybe we want this to say status ID field must be a number or array of numbers or omitted, we could do that as well. So, let's jump back into our text editor, back into our number filter.
05:56
And off of our union, we can add an additional call to otherwise.
06:01
And this accepts in a callback function that will be called whenever the conditionals within our union array all return back falsy.
06:08
Since we have an else, though, that means that it will always capture it and will never result in our otherwise being called, which we'll fix here momentarily.
06:15
So, we can do underscore and we can get back the field information from this. The underscore that we've applied here is just the value that we're trying to validate against.
06:23
We don't need to use that to alter the error rule here. So, I'm just calling that underscore.
06:28
And what we can do is if our value does not match either one of these rules, then we can use our field context to report an error.
06:37
And the first argument to this is our error message. So, we could say something like field name, which in our case would be status ID with our test over in Hopscotch.
06:45
So, status ID must be a number, array of numbers or omitted. Then we want to give the rule name.
06:53
So, this could just be a generic name for this number filter rule. So, something like array of numbers or number optional.
07:01
And then we need to pass in the field context information as well. So, we can give that a save.
07:06
And now, if our union is not satisfied by the value provided, this otherwise will be called, reporting our custom error.
07:13
We're not quite done yet, but let's stop and see exactly what we get with this currently. Because right now, within our union, we're kind of satisfying both conditions.
07:21
It either needs to be an array or with our else, it needs to be a number or optional. So, technically, we're never going to fall back to this otherwise.
07:29
And then we can verify that by jumping back in our Hopscotch, sending it off one more time, and we still get our same validation error. Because our else is applied asserting that it should either be a number or undefined.
07:38
So, what we need to do is switch our else to another if to do an else if here. We can type the value in, and then we can check to see if we don't have a value,
07:48
or if the type of our value equals a number to satisfy the rule that we're applying there, type number or optional.
07:55
Now, we have a fallback where if we're providing in a string value, neither one of these if statements are going to be true, which will result in our otherwise being matched and utilized.
08:04
So, if we give that a save, jump back in the Hopscotch, send this off one more time, now we're getting our custom error status ID must be a number, array of numbers,
08:12
and we're committed with our custom rule and the field information there. Cool. So, now we have our advanced number filter set up as well,
08:19
allowing us to send either just a plain number or an array of numbers, and we also have a custom fallback error message as well if neither of those are met.