53-Nodejs Course 2023: Http Events: Validation Events
Tags: node, typescript, mongodb, fastify
Published: 2022-11-09 14:34:16

---
title: 53-Nodejs Course 2023: Http Events: Validation Events
published: true
description: 
series: Nodejs Course 2023
tags: nodejs, typescript, mongodb, fastify
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2aqahhyzosvopkucm8sr.png
# Use a ratio of 100:42 for best results.
---

So we got to know about the http events in the previous article. Now we will see how to use the events in the validation.

## Validator Events

As i mentioned earlier, there are multiple events that can be fired during the validation process, let's review them:

* `validation.validating`: This event is fired when the validation process starts.
* `validation.passes`: This event is fired when the validation passes.
* `validation.fail`: This event is fired when the validation fails.
* `validation.done`: This event is fired when the validation is done either it passes or fails.

Now let's implement these events in our application.

Before we move on, if you remember we instantiate the validator class on each request, so we need to make sure that the events are triggered on each request, but to allow listening to it, we will have to make this event listener method `static`.

Open `src/core/validator/types.ts` and add the following:

```ts
// src/core/validator/types.ts

/**
 * Validation event types
 */
export type ValidationEvent = "validating" | "passes" | "fails" | "done";
```

Here we defined the validation event types.

Now let's implement the `trigger` and `on` methods.

```ts
// src/core/validator/validator.ts

import { ValidationEvent } from "./types";

export default class Validator {
  // ...

  /**
   * Trigger validation event
   */
  protected static trigger(eventName: ValidationEvent, ...args: any[]) {
    return events.trigger(`validation.${eventName}`, ...args);
  }

  /**
   * Listen to the given event name
   */
  public static on(
    eventName: ValidationEvent,
    callback: (...args: any[]) => void,
  ) {
    return events.subscribe(`validation.${eventName}`, callback);
  }
}
```

We added the `trigger` and `on` methods to the validator class.

The `trigger` method will always receive multiple arguments based on the event type.

The `on` method will receive the callback that will receive the arguments passed to the `trigger` method.

Let's define what arguments will be sent.

* `validating`: will be triggered before looping over the rules and receives the rules list, input values and validator instance.
* `done`: will be triggered after looping over the rules and receives validation state (wether passed or failed), the rules list, input values and validator instance.
* `passes`: will be triggered when the validation passes and receives the rules list, input values and validator instance.
* `fails`: will be triggered when the validation fails and receives the rules list, input values and validator instance.

Now let's start triggering some fireworks.

```ts
// src/core/validator/validator.ts
import events from "@mongez/events";
import { ValidationEvent } from "./types";


export default class Validator {
  // ...
  
  /**
   * Scan the validation rules
   */
  public async scan() {
    // get inputs values
    const inputsValues = this.request.only(Object.keys(this.rules));

    // 👇🏻 trigger the validating event
    Validator.trigger("validating", this.rules, inputsValues, this);

    for (const input in this.rules) {
      const inputValue = inputsValues[input];
      const inputRules = this.rules[input];

      const rulesList = new RulesList(input, inputValue, inputRules);

      await rulesList.validate();

      if (rulesList.fails()) {
        this.errorsList.push(rulesList.errors());
      }
    }

    // 👇🏻 trigger validation done
    const passes = this.passes();
    Validator.trigger("done", passes, this.errorsList, this.rules, inputsValues, this);

    // 👇🏻 check if validation passes, then trigger the passes event
    // otherwise trigger fails event
    if (passes) {
      Validator.trigger("passes", this.rules, inputsValues, this);
    } else {
      Validator.trigger("fails", this.rules, this.errorsList, inputsValues, this);
    }
  }
}
```

The code is pretty much self-explanatory, we trigger the `validating` event before looping over the rules, then we trigger the `done` event after looping over the rules, and finally we trigger the `passes` or `fails` event based on the validation state.

Now we can try listening to these events.

```ts
// src/app/users/routes.ts
import Validator form 'core/validator';

Validator.on('validating', (rules, inputsValues, validator) => {
  console.log('validating', rules, inputsValues, validator);
});

Validator.on('done', (passes, errors, rules, inputsValues, validator) => {
  console.log('done', passes, errors, rules, inputsValues, validator);
});

Validator.on('passes', (rules, inputsValues, validator) => {
  console.log('passes', rules, inputsValues, validator);
});

Validator.on('fails', (rules, errors, rules, inputsValues, validator) => {
  console.log('fails', rules, errors, rules, inputsValues, validator);
});
```

> Please note that we'll send the errors list in both events `done` and `fails`, in `done` event if passes, then the errors list will be an empty array.

And That's it!

Now we have a more super powerful validator by adding the events system to it.

## 🎨 Conclusion

In this article, we learned how to use the events system in the validation process.

In our next article, we'll start implementing **the requests events**.

## 🚀 Project Repository

You can find the latest updates of this project on [Github](https://github.com/hassanzohdy/nodejs-2023)

## 😍 Join our community

Join our community on [Discord](https://discord.gg/pb2vmdfhGf) to get help and support (Node Js 2023 Channel).

## 🎞️ Video Course (Arabic Voice)

If you want to learn this course in video format, you can find it on [Youtube](https://www.youtube.com/playlist?list=PLGO8ntvxgiZMJc7RN2lIq9WmMOlWZGzmz), the course is in Arabic language.

## 📚 Bonus Content 📚

You may have a look at these articles, it will definitely boost your knowledge and productivity.

General Topics

* [Event Driven Architecture: A Practical Guide in Javascript](https://dev.to/hassanzohdy/event-driven-architecture-the-best-paradigm-that-i-love-to-work-with-in-javascript-and-node-js-1gnk)
* [Best Practices For Case Styles: Camel, Pascal, Snake, and Kebab Case In Node And Javascript](https://dev.to/hassanzohdy/best-practices-for-case-styles-camel-pascal-snake-and-kebab-case-in-node-and-javascript-55oi)
* [After 6 years of practicing MongoDB, Here are my thoughts on MongoDB vs MySQL
](https://dev.to/hassanzohdy/after-6-years-of-practicing-mongodb-here-are-my-thoughts-on-mongodb-vs-mysql-574b)

Packages & Libraries

* [Collections: Your ultimate Javascript Arrays Manager](https://dev.to/hassanzohdy/collections-your-ultimate-javascript-array-handler-3o15)
* [Supportive Is: an elegant utility to check types of values in JavaScript](https://dev.to/hassanzohdy/supportive-is-an-elegant-utility-to-check-types-of-values-in-javascript-1b3e)
* [Localization: An agnostic i18n package to manage localization in your project](https://dev.to/hassanzohdy/mongez-localization-the-simplest-way-to-translate-your-website-regardless-your-favorite-framework-4gi3)

 React Js Packages

* [useFetcher: easiest way to fetch data in React Js](https://dev.to/hassanzohdy/usefetcher-the-easiest-way-to-fetch-data-in-react-45o9)

Courses (Articles)

* [React Js: Let"s Create File Manager With React Js and Node Js](https://dev.to/hassanzohdy/lets-create-a-file-manager-from-scratch-with-react-and-typescript-chapter-i-a-good-way-to-expand-your-experience-5g4k)