Elec

@Elec_crafter

Create directive for showing error message in form with Angular

Form and validation are fundamental in website. Angular provide easy way to handle validation in form but we can still simplify more validation work with directive.

In this post, I’ll show you how easily show validation error message without *ngIf and long expression.

I assume you’ve already familar with Angular, I suggest you read these topic if you don’t know them.

The problem in validation.

Showing message to the user makes our code looks ugly. For example

Before add validation message

After add validation message

Ewww. it’s so mess now. 😵

So I’m trying to get rid of duplicated code with directive magic. Here it’s what I achieve.

It does looks a lot cleaner. 😻

This is achieved by 2 directives. invalidmessage and invalidType.

InvalidmessageDirective

invalidmessage directive receive form control by name and set visible of hosted element based on the form control’s error.

Here’s the code of invalidmessage directive.

Don’t worry, I will explain code soon.

invalidmessage directive

First, I inject ControlContainer for get Formgroup instance from nearest parent’s injector (it’s myForm in the above example ).

get FormGroup with getter(excerpt from invalidmessage directive)

Now we can easily get from control by name (eg,this.form.get('yourcontrolname') ). 😎

FormControl instance can get value, error and so on. Actually it’s just form control that you use in ReactiveForm. For example, this.myform.get('name');

I create setVisible() method for set hosted element visble when the control is valid and hidden when it’s not.

set visble based on control error (excerpt from invalidmessage directive)

Showing error message at first is really bad (Many Ux website told that) so it’d make user less grumpy if it just show when user interact with control or click submit button already. I check that with this.control.dirty and this.hasSubmitted in the above .

setVisible() method will be called when value of control is changed and when user click submit button.

setVisible will be caledd when controlValue$ emit (excerpt from invalidmessage directive)

Notice Observable.of , it’ll emit immediately so setVisible() will be called at initial.

formSubmit$ is Observable that emit when form is submitted. It’ll set hasSubmitted to true.

invalidmessage provide match method for invalidType directive to call for checking if it match control’s error type.

match take argument which it’s error type and check if control has that error or not(excerpt from invalidmessage directive)

this.control.errors is object whose propery name is error type. Say, form control has required and email validations and user break it. FormControl errors object will be like this.

{
required:true,
email:true
}

You’ll see how it’s used in the next section.

InvalidTypeDirective

This directive is for set visible of host element based on error type of control which control difined in invalidmessage directive.

As you may notice in the above example,*invalidmessage . There’s asterisk prefix. It’s called Stuctural directive. For short, Stuctural directive will create ng-template surrounding host element which make host element won’t be rendered until you explicitly render with ViewContainerRef

Let code explian itself

invalidType directive set visible error message based on control error

This directive is injected with 3 dependencies — InvalidmessageDirective, TemplateRef and ViewContainerRef.

TemplateRef and ViewContainerRef are for create and remove host element(which it’s error message).

Angular inject instance of InvalidmessageDirective that is nearest parent injector.

<div invalidmessage="name">
<p *invalidType="'required'">Please provide name</p>
</div>

InvalidTypeDirective which is on <p> can get instance of invalidmessageDirective (which is on <div>) by injecing InvalidmessageDirective in invalidTypeDirective as we did above.

So invalidType directive can use property and method of invalidmessage directive instance.

setVisible() for set visible of host element based on invaludmessage’s match medthod (excerpt from invalidType directive)

invalidmessage’s match method take a type of error by argument(which it’s defined with type property) and check if error object has the specified error type.

If invalidmessage’s match return true, view container will create view from TemplateRef (it’s ng-template surrounding hosted element) and view container will clear when it’s false. In layman’s term, invalidType directive show and remove host element based on return value of invalidmessage’s match method.

It need to check if view container hasn’t created by checking hasView property so it won’t create repeatly.

setVisible() is called when invalidmessage’s controlValue$ emit (excerpt from invalidType directive)

setVisible() is called when invalidmessage’s controlValue$ emit(control value change and user click submit button).

That’s all. These two directives can simplify our form validation. It’s maybe not perfect but it can give you an idea.

If you have any question or suggestion, please comment below.

Here’s plunker

If you like this post, please leave a like ❤️ and follow me on Medium or Twitter to read more about Angular, Javascript and more.

Hacker Noon is how hackers start their afternoons. We’re a part of the @AMI family. We are now accepting submissions and happy to discuss advertising & sponsorship opportunities.
If you enjoyed this story, we recommend reading our latest tech stories and trending tech stories. Until next time, don’t take the realities of the world for granted!

More by Elec

Topics of interest

More Related Stories