JOE:
John's not here but Barry Manilow is.
[Does your team need to master AngularJS? Oasis Digital offers Angular Boot Camp, a three-day, in-person workshop class for individuals or teams. Bring us to your site or send developers to ours -AngularBootCamp.com.]
[This episode is sponsored by Wijmo 5, a brand new generation of JavaScript Controls. A pretty amazing line of HTML5 and JavaScript products for enterprise application development, Wijmo 5 leverages ECMAScript 5 and each control ships with AngularJS directives. Check out the faster, lighter and more mobile Wijmo 5.]
CHUCK:
Hey, everybody. Welcome to Episode 22 of the Adventures in Angular Podcast. This week on our panel, we have Joe Eames.
JOE:
Hey, everybody!
CHUCK:
John Papa.
JOHN:
Hey, everyone!
CHUCK:
Lukas Reubbelke.
LUKAS:
Hello!
CHUCK:
I'm Charles Max Wood from devchat.tv. And this week, we have a special guest, Kent Dodds.
KEN:
Hi there!
CHUCK:
Do you wanna introduce yourself, Kent?
KEN:
Yeah. most people know me on Twitter as @kentcdodds. And I am a developer here in Utah. I work for a company called Alianza we're a Voice over IP company for ISPs. So, I've been doing Angular for about a year and a half and loving it.
CHUCK:
Awesome. Well, the topic for our show today is form validations. Do you wanna kind of give us a brief intro or overview?
KEN:
Form validation in Angular can be a little bit -- well, form validation in general, regardless of your framework -- can be a little tricky because you're taking arbitrary input from a user and you need to verify that it's to whatever specifications you have; whether it's a phone number or Mac address or an email address. And Angular provides a lot of really cool things that help with this, but I think that in the community, lots of people don't take full advantage of what Angular really is and that's it's not just a bunch of ng-clicks, ng-models, ngForms; you have a lot more at your disposal that can really help you out with forms and validation.
And the validation is also something that I think people really overlook because it can be so difficult. And so that's why with all the projects that I've done, forms have been a huge part of what you’re actually trying to accomplish. Lots of the CRUD apps that we build with Angular. And so having a good solution for forms is really important to make your life easier, make your application maintainable and make it so that you're able to pivot when a product comes and says, “Hey, we wanna change this about our application. We wanna change the look and feel. We wanna change the voice of the application,” you need to be able to make those kind of pivots. And if you build your application right as far as your forms are concerned, that can be a pretty trivial thing.
JOHN:
So if we could set a little bit of foundation for forms and validation -- let's forget Angular for a minute – just an HTML, HTML5 itself has a whole bunch of validation attributes that people can use, right?
KEN:
Yeah.
JOHN:
And then on top of that we can then use Angular directives to enhance how the form validation works based upon the models that Angular has.
KEN:
Yeah. And especially with Angular 1.3, if you are on that version (if you're not, I definitely recommend you get on that version as soon as possible) but with Angular 1.3, they bring in the ngMessages module, NgModelOptions, directive and then the async validators and the validator pipelines which make validation a breeze. It's really nice. But yeah, going back to just standard HTML5 attributes, Angular actually does jump on top of lots of those attributes like require, disable and maxlength and minlength. and I can kind of help you with validation just by hooking into those standard HTML5 attributes but you can utilize the directive versions of those attributes for a little bit more control as well.
CHUCK:
A lot of that went right past me. [Chuckles] I'm just going to admit it. So let's say I have a form and I wanna validate, let’s say I have like a name and email address, maybe a credit card number or something. I'm just thinking of something. A dollar amount so they have to put in like a correctly formatted number or something. How do I go about setting all that up?
KEN:
There’s the easy way to setup and that's the hard way to maintain; and then there's the more difficult way to setup but much easier to maintain. So one thing that you can do is there’s a directive called ng-pattern. And actually it's HTML5 attribute that's a pattern and that takes a regular expression that you can use for validation. And Angular will hook right into the pattern attribute and will validate the model based on that regular expression that you give it. And so like if you wanna stick in a crazy, huge validator for credit card number or URL, be my guest. But it's actually a lot easier to use Angular as validator’s pipeline to be able to validate your stuff in.
And like the validator pipeline is part of the ng-model controller. And so you could say you create a
directive that's like your credit card validator and you just stick that directive as an attribute on that input that has the ng-model. And then with that, you require the ng-model controller and then you can add a validator to that pipeline or to that controller’s validation pipeline. And that validation pipeline is just essentially object that has keys as the name of the validator and then the value is the function that validates and that's passing model value and the view value. And then you can like just do regular JavaScript to validate that and return “true” if it's valid, “false” if it's not. And then Angular will add that to the errors for that form control for that field.
So I guess like I said, this is a little bit more difficult to setup initially, but once it's set up, it makes your life so much easier and I highly recommend that you do things this way. There's a mantra that I wanna talk about that helps with this a great deal. So Angular does a lot for you behind the scenes to tell you what is valid and what's not valid about that particular field. And specifically like with that credit card if you will return “false”, then it will tell you, “Hey, this field is invalid and it's because the credit card is invalid or that credit card validator return false.”
JOHN:
Let’s say I'm a user. I come in and I'm typing in a credit card number. If somebody didn't put validation in the HTML, is there a way to validate it inside the JSON JavaScript object?
KEN:
Oh, I see. So like you're thinking just to validate the model itself rather than what’s in the input?
JOHN:
Right. Where it will also bubble up to the input as well, because if it's in the model, then no matter where you put it on different screens, it will be validated no matter how many places you have it. I am thinking you know you’ve got, let’s just say just username or email address, and you’ve got twenty of these things across your app. This way, if it's still in the model, it will be “everywhere” as opposed to me having to remember to go put it in 20 different places or using a directive to encapsulate that. So I'm just trying to understand where does the validation happen?
KEN:
Good question. So, yeah, the validation happens on the form level. And this is where I guess I can bring in the module that I was going to talk. There’s actually two modules out on GitHub that I’ve found one of them, I'm a maintainer of and trying to improve all the time and I use on all my projects. Another one was made by somebody else. The one that I have been working on is called Angular Formly. And basically, you tell Angular Formly, “Hey, here’s a bunch of templates of the different input types that I have. So I have like just a regular text input, I have check boxes, I have radio buttons.” All these different form controls. And you can provide even like controllers and there can be [?] directives.
But then as you start using these in your controller, you just say, “Here’s my array of fields.” And it's just a configuration, so at this point you’re configuring your inputs and you're not writing anymore HTML. Once you’ve defined what your templates look like, and you tell Formly, “This is what an input looks like. This is what an email looks like,” then from that point, you’re just configuring your fields and Formly will take care of showing those fields on the page for you. So it's just a directive, basically called Formly form. You provide it a result which is model that the form is going to represent, the fields which are the fields that are like your configuration, and then Formly will spit out the full form for you based on those field configurations and your model.
And so by doing things that way, you can say, “Hey, here’s an email input or here’s a credit card input, and I have these validators for that credit card input and you just have to do that in one place.” If somebody says, “Hey, your credit card validation is wrong,” and you have to change it in one place, you don't have to go through all the places you collect credit cards or all the places you collect emails; you just update it in that one place and then everybody who’s using that field type will benefit from those updates. And Formly also hooks into the validator’s pipeline from Angular 1.3 if you’re using 1.3. And so, like then, things just become like a breeze when it comes to doing validations. It's really slick.
And I use this on multiple of my projects, whether moonlighting or at work. And it's super nice. Like we're in that right now. I inherited a project that was just like, I guess the guy really knew how to write HTML. So he did it everywhere and just creates a lot of bugs when you have a ton of HTML that's like… HTML is just a huge configuration thing, and so you have a ton of the same stuff everywhere. You’re copy pasting everywhere. And so we have been moving this HTML mess. I don't wanna call it a mess, but this huge bunch of HTML into like really, really small directives where the bulk of it is just configuration of fields and you just do that in the controller. No big deal. And it has made our application a lot less buggy because everything is consistent. If we wanna change the styles of what labels look like or what an input field looks like, we're just doing it in the one place and it just propagates everywhere automatically for us. So it's been a huge help for us.
JOHN:
That sounds helpful. I guess just to kind of reset the line. We started out talking about HTML validation, what comes out of the box, and you get regex validators and things like that, but I think the reason Angular has all these extra features is because validation is more complicated and because of Angular’s features, we can add more functionality out of the box, so they are making us code like crazy. So would you kind of walk through -- since you’ve done a lot of work in this -- what would you say or the recommended steps if someone is getting into validation with Angular, the first couple things you'd ask them to do, especially since Angular 1.3 has a features in it.
KEN:
Yeah, I think knowledge is power for sure. And so, I would recommend anybody to learn what is available in Angular -- whether that be reading the Angular docs or going to Plural Sight or Egghead.io -- just learn what’s available because based on my experience with looking at other Angular projects, people don't know that ngMessages module is legit and ngModel and ngModelOptions and ngForm have a lot of things that we can do with them. Particularly, ngModel controller has a lot of things that you can hook into.
And lots of people don't know this as well (I've noticed) but when you have a form or an ngForm in an Angular application, you give that form a name. Whatever you pass that name will be assigned to a variable on the scope. And so if I have a form and I've given it an attribute name as foo, then I can say scope.foo and that is a form object. And so then that has like a $errors and that shows to me all the errors in that form. It like $setPristine(),$setDirty (). Like, actually invalid and valid are like crazy easy for enabling and disabling a save or a reset button because you don't want people to be able to submit the form if it's invalid. And I've seen this countless times where you have a function that goes through your model and checks everything to make sure, “Oh, did they fill out everything that they're supposed to on all the required fields?” But it's so much easier to say, “If this form is invalid, then don't let them click the “submit” button.” Or if they do, I show them an error message of some kind.
And even better than that, like going on to the form control level, so if your form has a name and it's assigned on a scope, then all of the fields with an ngmodel on it, if those have a name, the name of that is assigned as a property on that form. And so if I have a form named foo and an ngmodel input named bar, then I can say “foo.bar.errors” like $errors and that will be a hash of all the errors of that field. And I can show like real time messages of what is actually wrong with that field and using the ng-messages module like makes that crazy easy.
So it's just about caring about your users and what making sure that they're using your application properly and they are assisted hand held through the whole process. And using something like Angular Formly or the other modules Angular Form Schema, I think. But using something like that to kind of abstract a way, [?] HTML that you have to do can really improve the maintainability of your application. And like, you don't have to worry about validation except in just one place and so yeah, it makes things a lot cleaner in your application throughout.
CHUCK:
I'm wondering, because we mentioned the HTML validations, so you have like an email field or phone number of field and it will validate it or the web page will actually, the web browser will validate it, should you do one or the other or can you run them both at the same time? Or does that even makes sense?
KEN:
That totally makes sense. Yeah, you can actually run them both at the same time. So if you're in… in most cases you will want to put “no validate” on all of your forms, and actually, in most cases, you’re likely to want to use ngform in the place of the regular form tag. Although it doesn’t provide you like the ngsubmit and action if you're posting to a server. But anyway, yeah, so you can use both. So if you say, “Hey, this input is type email and this is what I do,” Angular will automatically validate that as an email input and it will do its own validation. Because on the form, you wanna put “no validate” because browsers will do a UI to validate your form differently from one another.
And lots of times, that's not okay for product managers to just say, “Hey, we’ve got a style. We wanna do it this way.” And so you put “no validate” on your form. And then Angular will validate it for you whether you do that or not. You just say, “Hey, browser I'm going to deal with this myself.” And then if you have like an input type email, Angular will automatically validate that for you and add that to the like $errors on the form and $errors on the form control itself. And so like then you can show error messages based on that email. So you can definitely use the regular HTML5 attributes on your ngModel inputs, and yeah, that works just fine.
CHUCK:
So the other question I have then -- and it sounds like the answer is “yes” -- is are there any built in validations that I can use? For example, validating an email or validating a phone number or validating that it's all numeric values or something like that.
KEN:
I'm pretty sure that this is true but anything that’s supported by the browser, like regular HTML5, Angular supports. I'm almost positive that's true. Definitely email. I know I’ve seen the regex in Angular that validates the email. And obviously, like the Angular teams at Google where they have access to like the Chrome team and so they can make sure, “Hey, are we validating the same way that Chrome is?” And make sure that’s legit. So, most things, there’s something built in. But like you have one off case.
Like for example, a phone number, I don't think that HTML5 supports validating a phone number. I could be wrong, but I don't think that they do. And so I don't think Angular does either. So where I
work, we’ve Voice over IP, so phone numbers are kind of a big deal for us. And so, like we have our own validation for phone numbers. Phone numbers are actually really interesting to validate but yeah, so we have our own validation for phone numbers. And really, it's just like a function that returns “true” if it's valid. So it's crazy easy using the validators pipeline to do that. Did that answer your question?
CHUCK:
Yeah. I'm just thinking the possibility of creating an extension for Angular that includes a whole bunch more.
KEN:
Oh yeah, totally. And I wouldn't build anything without something like this, but I have a factory that’s basically just a big list of everything that I like to validate. So I should pull it up, but I've got phone number in there, Mac address, I don't think I have credit card, like yeah, I got a bunch of like the less common things that you validate in there, so that anywhere in my application, I say, “Hey, Formly, here’s a field I'm configuring and here’s the validator for phone number, and here’s my validator ,” and just reference the function in that validator’s factory. Actually, I have an abstraction on top of that, so I don't even have to do that everywhere. But yeah, totally.
And like I said, I wouldn't build a real, big application without doing something like that to keep your validators in one place, so that when somebody says, “Hey, there's something wrong with this field’s validation.” You just go to the one place to update that, like that validation type. Because if there’s a problem with this fields, phone number validation and there should be a problem with all the phone number validation because you shouldn’t be copy pasting that code. And actually, like you said, Chuck, like building a library, I wonder if a module exists that does this. What actually would be a good JavaScript in general library wouldn’t have to be an Angular thing at all, but just a whole bunch of functions that validate different types of user input. That would be awesome.
CHUCK:
Or you could build that library that's a phone validator and it's just the function that runs regex or however you're going to do it. And then you could build an Angular extension on top of that that just gives you all the directives.
KEN:
Yup. Totally.
CHUCK:
Anyway, we're running close to time. Is there anything else that we should talk about on this?
KEN:
No. I just do wanna say that like field validation is about caring about your users and their experience with you application, and so you don't want them to like this long form, hit the submit button, and then like go to the next page and get an error that says, “Hey, you’ve missed this field… idiot.” [chuckles] you want them to have a good experience interacting with your application.
JOHN:
It's usually not very nice to call your users “idiot” but…
KEN:
Yeah. [Laughs]
CHUCK:
He was calling me an idiot.
KEN:
[Laughs] So, like I said, validation is about like showing that validation for your users. It's about caring about your users. And also, like I wanna put in a plug for accessibility as well. By using something like Angular Formly or your own abstraction… Matias, I’ve got a pick, of a video meet up but Matias built kind of his own abstraction, similar to Formly, but I definitely highly recommend that you do this, because when it's less difficult for you to code up a form control -- like an input, a radio button or something -- it makes you… like you have more time to focus on other things that really matter, like accessibility and validation for that matter. And so, definitely like, it's about caring about the people who are using your application.
JOHN:
Kent, can you give us your 60-second pitch on why ngMessages, that module for Angular 1.3 was created and what the value in that is?
KEN:
Yeah, totally. So if you're not familiar with the $errors that gets attached to a form or a field control, then this will make a little bit less sense to you, so I recommend to go looking into that. Or if you haven’t like shown real time error messages to your users on your forms, I definitely recommend that you do, but ngMessages makes that whole process a million times easier. So what you used to do is like… so that errors is basically a hash of all of the fields that are in error. So you have four fields that are required and only two of them are filled out. Well, the two that aren’t filled out will be in an array that's called required, so the key is the validator that's failing. And then the array is the fields that are invalid because of that key, so that validator that's failing. And those two fields that are required that aren’t filled in will be in that array.
And so, what you wind up doing is you say, “Okay, on this form, I want to show this message. If this field is required and it's like in that array, and if this thing is in that array too.” And then, “Oh, I also have a max length and I also have email and I've got all this if’s. And I only wanna show one message at a time, so I’ve got to make sure if there’s only one message…” and like it turns into a real big mess very, very fast. And so with ngMessages, it just abstracts all this away from you and you just say, “Hey, ngMessages, you're a directive and here’s my errors object.” And then you just provide a list of messages that says, “Hey, this is the message I want you to show when there’s a “required” error and this is the one I want you to show when there’s an email error and blah, blah, blah,” all the different error types and it will display all those for you. And so that was a little bit longer than sixty seconds, but that's the basic gist is it just makes your life like incredibly easier when it comes to displaying Messages to your users about form errors.
JOE:
And is it the best thing ever?
KEN:
Right after chocolate milk.
LUKAS:
And peanut butter and jelly.
CHUCK:
Awesome.
KEN:
Yeah. [Chuckles]
CHUCK:
All right. I hate to push this along this way, but we had one or two people say that they had a hard stop, so I'm going to push us into picks. And we'll have John Papa start us out.
JOHN:
So my first pick is going to be basically a theme (it's more like a tip, I guess) a theme that Kent was going along, that’s I like to say that validation in the client is a user experience; on the server, validation is a necessity. So just like security, you want to do that kind of stuff in the client user experience for validation and security but on the server, you wanna do that. It's a necessity. Don't skip one or the other. Have both of those. And then for my tip, I'm going to say definitely check out Kent’s different libraries got out there. There's pretty cool stuff going on.
KEN:
Thanks!
CHUCK:
Joe, what are your picks?
JOE:
I'm going to pick a timing tool that I've been using recently just to track my time because I'm kind of interested in not just how many hours I spend each day, but really how those hours are spent. I'm interested in tracking that, so I can try to fine tune and not spend too much time on activities that are less important. And I was looking for something that wasn't about a big team time tracking and time sheets and stuff like that, but just was like, “Track my time and give me an easy way to see how it’s spent.” And I’ve found this tool called Toggl. Toggl.com. it's free and it's really awesome. Good user interface. It gives you this nice little summary at the bottom of like your week, how you spent your week across different projects that you do. And I've really enjoyed it. Super awesome tool. So that's going to be my pick for this week.
KEN:
I've used that tool. It's pretty awesome.
JOE:
Yeah. I really like it. And then for my tip of the week, I'm going to say that you should only be using one module unless you truly understand why you're not using one module in your Angular projects.
JOHN:
Wait, wait, wait. Can you say that again? I'm a little sick. [Laughter]
JOE:
Use one module unless you understand why you should use more than one module.
JOHN:
Gotcha.
JOE:
The reason most people use an extra module is not actually a good reason. There are good reasons to use more than one module, but the reason most people use more than one module is not a good reason.
CHUCK:
Awesome. Lukas, what are your picks?
LUKAS:
So I'll go with the tip first and then I will go with the pick is I did a blog post on the signup form on my blog onehungrymind.com. And Marcy Sutton who is kind of the Angular accessibility expert called me out and said, “You should actually use ngAria on this, to make it accessible for people with disabilities.” And I was like, “Well, how do I do that? What do I do?” And I realized you simply have to just add the ngAria submodule to your Angular application and it would do everything for you behind the scenes. So really, really fantastic. So there’s no reason if you’re doing Forms not to use ngAria. And then my pick is actually Kent Dodd’s videos on Egghead. I have found it to be really helpful. I actually have continued to learn stuff as he puts videos on. I think they are really good. And so, definitely give them a look. And so really good work on those, Kent. I really appreciate them.
KEN:
Thanks, dude. Same to you! Architecture is important, dude.
LUKAS:
Hug!
JOHN:
This is the Kent Dodd’s Love Show.
KEN:
[Laughs]
LUKAS:
Oh yeah.
KEN:
Actually, it's funny. I was just going to say, I did an Egghead video on the ngAria module, and it was just so easy, that I had to fight to find stuff to make it longer than a minute.
CHUCK:
That's a glowing recommendation if I’ve ever heard one.
KEN:
It's awesome. Yeah, it's very easy.
CHUCK:
All right. I have a pick and a tip. My pick is The Life On Fire Virtual Summit. You can get it at lifeonfirevirtualsummit.com. Nick Unsworth is just interviewing all kinds of awesome people. One thing that I did though is they have a paid option and I got in when it was a donation of $97and now it's $197 but all that money goes toward building a school in Guatemala. And then you can actually listen to all the interviews and stuff on the virtual summit for free, so you don't have to pay. When I donated though, I got access to a whole bunch of extra stuff. So a lot of the people that he's interviewing gave up like digital courses and things like that. And so I got all kinds of extras when I did it. I've been going through one of those right now and it's just been really, really cool. I really like it. So if you're doing entrepreneurial stuff, then go check that out. We'll put a link the show notes.
And my tip is more of just a general programming tip, and that is I’ve found that in general (this isn’t always true, but is generally true) if you can break logic up into smaller functions and put names to things that you're going to put anonymous functions on, then your code becomes easier to read because then you have intention revealing names that give you information about what's going on without you having to actually know the implementation details until you care about them. So that's my tip. Kent, do you have a pick and a tip for us?
KEN:
So my first pick is Complex Forms at Mountain at View AngularJS Meetup. This was the video I mentioned earlier from Matias. He kind of built his own mini formly, but he had a lot of really solid concepts in there that I think that people should know about. My second pick Christmas Lights. My wife and I are driving our kids around during this time of year when Christmas lights are up and they are just great. I like Christmas lights.
CHUCK:
Well I have to get notes so you can tell us where to go.
KEN:
There’s one street where like these neighbors definitely having a battle. It's awesome! And then obviously, I just like to pick Angular Formly. It's made my project so much easier. So go check that out for sure. And then my tip is the dot or even better, controller as. So if you haven’t run in to the problem with binding primitives, you're dodging a bullet because it such a pain in the rear. So like in your ngModels, make sure that you’ve got a dot in there, or even better, like use controller as syntax for everything because it will really hit you hard for hours, and it hurts.
CHUCK:
Very cool. All right, before we wrap up, I just wanna remind folks that we are doing JS Remote Conf. By the time the time this comes out, you’ve missed the early bird and the CFP, but we should have the schedule up pretty soon. So keep an eye out for that. You can find that at jsremoteconf.com and thanks for coming, Kent.
KEN:
Yeah, thank you for having me. It's been a lot of fun.
CHUCK:
All right. We'll wrap up and we'll catch you all next week!
[This episode is sponsored by Mad Glory. You’ve been building software for a long time and sometimes it gets a little overwhelming; work piles up, hiring sucks, and it's hard to get projects out the door. Check out Mad Glory. They are a small shop with experience shipping big products. They're smart, dedicated, will augment your team, and work as hard as you do. Find them online at madglory.com or on Twitter at @madglory.]
[Hosting and bandwidth provided by The Blue Box Group. Check them out at bluebox.net]
[Bandwidth for this segment is provided by Cache Fly, the world’s fastest CDN. Deliver your content fast with Cache Fly. Visit cachefly.com to learn more.]
[Do you wanna have conversations with the Adventures in Angular crew and their guests? Do you wanna support the show? Now you can. Go to adventuresinangular.com/forum and sign up today!]