Transcript from the "Shared Data Validation" Lesson
>> Kyle Simpson: Somebody asked in the chat how could we do something with some shared data validation code, right? So let's try that. Hadn't thought about it, but we'll just on the fly try to figure it out. So I will take my Foo.js module, and I'll make another module that I'm going to call validate.
[00:00:19] So I'll just say Save As, Validate.js. Take out its contents for now.
>> Kyle Simpson: Make sure to update the name there.
>> Kyle Simpson: All right let's start first by integrating it into the server. We could start either way but I'm gonna integrated in the server first. So I'm going to go back to where I'm listing my modules here.
[00:00:56] List another one called validate and then I'll come down here and load up a validate module.
>> Kyle Simpson: So now I have access to that validate module from inside of my code. So let's put some validation into our API call, let's actually send in some, we'll need to send in some data and validate that the data that we're sending in is correct.
[00:01:33] So I'm trying to think on the fly what kind of data would be appropriate. Let's think that
>> Kyle Simpson: We need to pass in two pieces of data, a min and a max. And they should be numbers and the min should be less than the maximum number. I'm just making up some data inputs that we could do some validation rules against.
[00:01:55] So we'll assume that the request URL is going to receive this information through a Get. So we're going to instead of wanting saying equal to foo, we're going to want to say the way we test this URL is to put in a regular expression so URL needs to start with /Foo.
>> Kyle Simpson: Now I want to parse out the parameters that might have been on my Get APIs, so I'm gonna say data =, and I've got a module already loaded in called url_parser here. So it's already gonna handle that URL parsing for me.
>> Kyle Simpson: And I think just req.url is what we want.
[00:03:24] All right, so that data is now gonna be an object with whatever my get parameters on my URL were. So now we're expecting that there should be a min property and a max property, and we want those to be validated. Okay, so what we're going to do first is we're gonna say, let's just assume our validations here are gonna be synchronous, but you could do asynchronous validation if you invoked promises.
[00:03:48] So we're going to say, we're gonna invoke our validate thing, and we're gonna say checkMinMax, that will be the method that we call it. And we're going to pass in data.min and data.max.
>> Kyle Simpson: So if that check succeeds,
>> Kyle Simpson: Then we wanna do this work that we were doing before.
>> Kyle Simpson: I forgot by the way it didn't bite us before but I forgot that we wanna always return true if we have an affirmative answer to any API request, so that the 404 doesn't try to play in. But if the validation fails,
>> Kyle Simpson: Then I want to do
>> Kyle Simpson: Let's send back a JSON response.
>> Kyle Simpson: I could have pulled that error message from the validator, but I'm not gonna go to that step. So let's just, we'll ask Validate.checkMinMax it should give us a true or false. If it's true we'll proceed and respond with an API request.
[00:05:39] If it's false we'll let the browser know that there was a failure by sending back a JSON object with an error in it, okay.
>> Kyle Simpson: So now let's write that validate rule. We're gonna have a function that's called checkMinMax takes in a min and a max number. And it, the first rule that we'll say is if,
>> Speaker 2: Did you get the data values?
>> Kyle Simpson: What's that?
>> Speaker 2: Don't you need the value you're checking?
>> Kyle Simpson: What do you mean?
>> Speaker 2: MinMax is a bound right?
>> Kyle Simpson: Yeah but those are the things that we're passing in, we're gonna use MinMax to constrain our random numbers.
>> Speaker 2: Gotcha.
>> Kyle Simpson: So we're checking to make sure that MinMax is what we want to be, okay? So let's say that, just for simplicity, we're not gonna do data transformations here. You could've done a data formatting on the inbound requests but let's just do our data formatting in here. We'll make sure that Min is definitely a number.
[00:06:59] So there's our coercion playing in, make sure it's definitely a number and make sure Max is also definitely a number. Oops, all right so the first way that this is gonna fail.
>> Kyle Simpson: The first way that this would fail is if Max was less than Min. We should respond back, nope that's not good.
[00:07:29] So we can just do a return false rather than sending an error message here. But that's one way that it should fail. And let's say that another way it should fail is if Min is less than zero, that's also a failure case. So let's fail the validation there and if Max is greater than 100, just making stuff up.
[00:07:52] Those are our three data validation rules. Now the point I want to make about data validation that we're going to share in this way, is that this is essentially stateless data validation. We don't need to know anything about our back end state to do this. So checking to see that an email address is well formed is a stateless validation.
[00:08:15] Checking to see that an email address is unique within your system, that's not stateless that's stateful. And you can't really do stateful validations entirely in the browser. So we're constraining ourselves, the shared data validations are ones that are stateless, okay? So if all of those pass, then we just simply return true.
>> Kyle Simpson: Now this function, as written, does not care in any way shape or form what environment it's running in. It's just a data thing, it just does some data checks, okay? We're passing in a min and a max and it's just going to answer true or false. Let's expose that on our public API.
>> Kyle Simpson: Here's how we were using it on the server. And let's just make sure so Validate.checkMinMax, the min and the max should definitely come in correctly, so that should work. Let's actually use those though to actually constrain our Foo random number. So let's start out num being that random number, but that's a floating point.
[00:09:21] So if we said num* 1E9, which is a really, really big number,
>> Kyle Simpson: And we say math.trunc, so that truncates it. So now we have a really, really big random integer. Now what we wanna then say the way that we constrain it to a min and a max, is that we're going to do math.
[00:09:54] I'm sorry, we're gonna take that number that's been constrained, we're gonna mod it by data.max.
>> Kyle Simpson: We're gonna mod it by the subtraction of those, so (data.max- data.min). So if I said that the minimum should be 5 and the maximum should be 10, we'll subtract those two. So we're gonna mod our big number by 5.
[00:10:25] So we're gonna get values from zero to four and then we're gonna add back in our data.min. Don't worry if that math sounds kinda crazy, I've just done it a bunch of times. That's how you're gonna constrain a random number to a particular range. So now I'm gonna say that's my new num.
>> Kyle Simpson: So now instead of sending back some kind of floating point thing, I'm sending back a piece of data that has definitely. Now actually, now that I'm thinking about it, that logic is something we want to do in both places. We want to do that on the browser and in the server.
[00:11:12] And here we've constrained it to only happening inside of our API handler. This is something that the Foo random method should do, right? So let's take that code actually, the code that I just wrote. Let's put it inside a Foo, let me open back up Foo.
>> Kyle Simpson: Let's say that the Foo random takes a min and a max.
[00:11:43] That's different than what the Math.random takes. So let's put this logic here. Let's say first that num = Math.random and then let's say return the stuff, and we just need to update it, it's not referring to data.max and data.min anymore.
>> Kyle Simpson: The benefit of our data validation rules are we know that max is already greater than min because we've already validated that.
[00:12:21] We would not have gotten to this point if that validation hadn't already happened, okay? So now it's going to return me back a random number that's constrained to a particular integer range.