DEV Community

Cover image for 53-Nodejs Course 2023: Http Events: Validation Events
Hasan Zohdy
Hasan Zohdy

Posted on • Updated on

 

53-Nodejs Course 2023: Http Events: Validation Events

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:

// src/core/validator/types.ts

/**
 * Validation event types
 */
export type ValidationEvent = "validating" | "passes" | "fails" | "done";
Enter fullscreen mode Exit fullscreen mode

Here we defined the validation event types.

Now let's implement the trigger and on methods.

// 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);
  }
}
Enter fullscreen mode Exit fullscreen mode

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.

// 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);
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

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.

// 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);
});
Enter fullscreen mode Exit fullscreen mode

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

😍 Join our community

Join our community on Discord 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, 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

Packages & Libraries

React Js Packages

Courses (Articles)

Top comments (0)

11 Tips That Make You a Better Typescript Programmer

typescript

1 Think in {Set}

Type is an everyday concept to programmers, but it’s surprisingly difficult to define it succinctly. I find it helpful to use Set as a conceptual model instead.

#2 Understand declared type and narrowed type

One extremely powerful typescript feature is automatic type narrowing based on control flow. This means a variable has two types associated with it at any specific point of code location: a declaration type and a narrowed type.

#3 Use discriminated union instead of optional fields

...

Read the whole post now!