![Hardcore Functional Architecture Patterns in JavaScript](https://static.frontendmasters.com/assets/courses/2020-04-03-hardcore-js-patterns/thumb.webp)
Check out a free preview of the full Hardcore Functional Architecture Patterns in JavaScript course
The "Creating a Validation Library" Lesson is part of the full, Hardcore Functional Architecture Patterns in JavaScript course featured in this preview video. Here's what you'd learn in this lesson:
Brian demonstrates how to architect an app around validation, and builds a validation library that combines different kinds of validations, and provides errors or a final object.
Transcript from the "Creating a Validation Library" Lesson
[00:00:00]
>> All right, so we're gonna go to validation, we're gonna make a validation library right quick. [LAUGH] So I just kind of pummeled you with all these monoids. But you can see how it hints at architecture, right? We're able to start to say like, our type of app is an async error handling thing or it's a report like thing.
[00:00:19]
And in this case, we're gonna do architecture around validation. So we're gonna say validations are a thing that combined. Fundamentally, if I have a validation and let's say, isPresent and I do that check and I wanna concat that with another one like isEmail. We take some objects and we'll take say object.name and object.email.
[00:00:50]
What I should get is, either the combined errors or the original object, right, the choice. So, we wanna build something that combines a bunch of validations and presents me with all their errors or a successful object that got through the gauntlet. So let's try to build this, and I'm going to go slow, ask questions.
[00:01:18]
But, we're already gonna kind of start with, what do we want to end up with? And I think a nice API would be this. We'll say validations is this thing where we have name isPresent, an email, isEmail, and so on. So we'll say like we'll take it further.
[00:01:45]
We could say, well, I wanna concat that with also isPresent, right? We'll do that before the end. But the idea is that we provide an object key value and I want the validation to correspond to the key and I wanna be able to combine and compose validations. Is everybody understand the framing of the problem, what we are trying to do?
[00:02:07]
Any questions on that, yep?
>> This, if we were to take it into different language, would just be a different type of objects, right?
>> Yeah, exactly.
>> Okay.
>> It could just be named Paris, I just wanna be able to provide, this is the attribute I wanna run this validation on.
[00:02:25]
And we wanna do something maybe like validate validations. [LAUGH] And then we'll give it some object and we hope to get our object back or a bunch of errors. All right, so let's go ahead and write isPresent. And, actually you know what, nevermind. Let's go ahead and write this validate first before we do anything else.
[00:02:52]
I like to start at the color, right? So I'm gonna create, so we already have this thing. Let's simplify it for now and we'll do this later. But we say, in fact, let's just start with isPresent on both. So we have a very simple use case, we're gonna start with the calling code and kind of work our way back up.
[00:03:12]
So we have our object that has a name. And, brian and an email, and that would be brian@brian.com. All right, great. And we'll validate that. So it will be our response and we'll go ahead and console.log whatever that response is. All right, great. So we have to go write validate, so let's do that.
[00:03:43]
And validations is the specification of key values, right? So that'll be like our spec object, I guess, I don't know. I'm terrible at names, just called our spec. [LAUGH] And then we have an object. We call it a record or whatever. And then what we wanna do is say object.keys on the spec.
[00:04:10]
So for each of these names, well, what if we foldMap that, right? We're gonna be combining everything, so start that in a list and foldMap here. We're fairly certain we're gonna foldMap right now is why I'm doing this. So bring in list. List=require immutable-ext. And what are we folding mapping them into?
[00:04:41]
Well, why don't we start with an either, right, either kind of already does this for us. We don't have to write anything. So let's go bring in either from our types. I do love this behavior, it's like tells me exactly where I am in the folder structure. It's worth the pain.
[00:05:00]
So, okay, so we have an either and we'll pull out the left in the right from the either. So we have those at our disposal. Great, so we're gonna do is say we're start with either of right as our empty. And then we'll start with either of the object as our initial initial object, right, and then our initial empty.
[00:05:25]
Because we wanna either return the right of the object or a left of a bunch of errors, and then we're gonna take in each key. Let's just kind of expand this out for a second, get rid of the curlies, don't worry. [LAUGH] And then what we'll do here is say, so if we call the spec key, that will get this thing out of that object, right?
[00:05:51]
The spec keys are the names and I can get the value which is the validation out. And we'll run the validation on the object key, right? Cool, and that should return us. We could say something like, well, if it's true, we'll return a Right of this value, right?
[00:06:12]
So right of the object, everybody's good, it worked. Otherwise, we'll return you a left of hey, let's just for the screen sake, we'll say key, boy, key bad. [LAUGH] Here we go. We're gonna start with that, see where it ends up. Okay, I'm gonna get rid of these.
[00:06:35]
So now we're returning an either and you either can cats so things are good. And I'll write isPresent, we'll say, I don't know it takes an x and it's just not X-ray. Cool, life is good. Let's see what happens. If I run this, node lib validations, of course I'm already in lib.
[00:07:01]
Why would I leave lib and come back? It's already right here. All right, cool. But what happened here? Why is it man? [SOUND] Concat is not a function, right must be holding something that must be concatenate. That's not we want. We don't wanna concatenate objects with objects wiht objects, right?
[00:07:22]
So we have a few decisions here to make, we can actually use another monoid that I didn't mention called first, [LAUGH] or as a semigroup. Because we can't make that monoid. But we could say, we'll use this object first, that always just takes the first one. And then my work.
[00:07:39]
I can go ahead and make that so it always keep the first thing. But I'll tell you right off the bat, what's happening here is Left is just gonna short circuit when it hits the first validation. And we don't want that. We want it to collect the errors, right?
[00:07:54]
Even if we put an array here, And we can actually demonstrate this instead of using First, I'll just put this in array because an array concats. In fact, it's called the free monoids because you can always slap something in there. So, it does end up giving us a either and if we stop doing this, just fold it out.
[00:08:21]
Give it, I'll write any functions. We would get the console.log, sorry. So we get a bunch of successes here. If I remove one, say name bad. [LAUGH] But if I remove both, we won't get named bad and email bad we just get the first one, right? And if I get the other one will get email bad.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops