LoginSignup
5
2

More than 3 years have passed since last update.

『Node.js 超入門』の express-validation を最新の仕様に修正する

Posted at

概要

Node.js 超入門(第2版) を読んでいたところ、バリデーションの箇所が本の通り書いているにも関わらずエラーが発生。 正誤表 を確認したところ、以下のような説明がありました。

本書で使用している Express Validator は、現在 ver.6 となり、仕様が変更されているため、本書の記述の通りでは正常に動作しなくなっています。

ver.5 にバージョンダウンすることでサンプルコードのまま実行することが出来たのですが、折角なので最新バージョンに修正して実行をしてみました。
本記事では、express-validator公式ドキュメントを参考に行った修正内容について紹介したいと思います。

修正内容

サンプルコード(ver.5 の書き方)

  • P.334~335 リスト6-4 より、修正の必要があるPOST時の処理について抜粋
    ※修正後と形式を統一するためフォーマッタで一部書き方等を修正してます
hello.js
router.post("/add", (req, res, next) => {
  req.check("name", "NAME は必ず入力して下さい。").notEmpty();
  req.check("mail", "MAIL はメールアドレスを記入して下さい。").isEmail();
  req.check("age", "AGE は年齢(整数)を入力下さい。").isInt();

  req.getValidationResult().then(result => {
    if (!result.isEmpty()) {
      var re = '<ul class="error">';
      var result_arr = result.array();
      for (var n in result_arr) {
        re += "<li>" + result_arr[n].msg + "</li>";
      }
      re += "</ul>";
      var data = {
        title: "Hello/Add",
        content: re,
        form: req.body
      };
      res.render("hello/add", data);
    } else {
      var nm = req.body.name;
      var ml = req.body.mail;
      var ag = req.body.age;
      var data = { name: nm, mail: ml, age: ag };

      var connection = mysql.createConnection(mysql_setting);
      connection.connect();
      connection.query("insert into mydata set ?", data, function(
        error,
        results,
        fields
      ) {
        res.redirect("/hello");
      });
      connection.end();
    }
  });
});

修正後コード(ver.6 の書き方)

  • express-validationの最新バージョン(記事作成時は6.4.0)で実行できるようPOST処理を修正
    ※バリデーション設定箇所以外にも今時のJavaScriptの書き方に変更している箇所もあります(varでなくconstかletで変数を宣言するなど)
hello.js
const { check, validationResult } = require("express-validator");

router.post(
  "/add",
  [
    check("name")
      .not()
      .isEmpty()
      .withMessage("NAME は必ず入力して下さい。"),
    check("mail")
      .isEmail()
      .withMessage("MAIL はメールアドレスを記入して下さい。"),
    check("age")
      .isInt()
      .withMessage("AGE は年齢(整数)を入力して下さい。")
  ],
  (req, res, next) => {
    const results = validationResult(req);
    if (!results.isEmpty()) {
      let re = "<ul class='error'>";
      const result_arr = results.array();
      for (const err of result_arr) {
        re += `<li>${err.msg}</li>`;
      }
      re += "</ul>";
      const data = {
        title: "Hello/Add",
        content: re,
        form: req.body
      };
      res.render("hello/add", data);
    } else {
      const name = req.body.name;
      const mail = req.body.mail;
      const age = req.body.age;
      const data = { name, mail, age };

      const connection = mysql.createConnection(mysql_setting);
      connection.connect();

      connection.query(
        "INSERT INTO mydata SET ?",
        data,
        (error, results, fields) => {
          if (error === null) {
            res.redirect("/hello");
          }
        }
      );

      connection.end();
    }
  }
);

修正概要

今回でexpress-validationを使った処理に関しては以下の部分を修正しています

  • requireによるモジュールのロードをapp.jsではなくhello.jsの冒頭で行う
    • サンプルの通りapp.jsで宣言した場合には『TypeError: check is not a function』が発生するため変更
    • エラー原因は調査しましたがわからなかったので、ご存知の方がいましたらコメントで教えていただけたら幸いです
  • check内容をpostメソッドの第2引数に記載
  • ver.5 ではエラー情報をreq.getValidationResult().then()resultを引数としてコールバック関数で処理していたが、ver.6ではvalidationResult(req)を定数resultに代入し、関数の中でその値を使って処理
  • notEmpty()はなくなっているので、not().isEmpty()のように宣言
  • エラーメッセージはwithMessage()をメソッドチェーンにして使用し設定

まとめ

以上のように修正することで、記事作成時の最新バージョン(ver.6.4.0)のexpress-validatorでもバリデーションを実行することができました。
よかったら参考にしてみて下さい。

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2