yuka-f
@yuka-f (ふじ)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

ejsで、forEachメソッドを用いて配列errorsに入ったエラーメッセージを表示したいです

解決したいこと

ejsで、forEachメソッドを用いて配列errorsに入ったエラーメッセージを表示したいです

Node.jsでユーザー新規登録機能の空入力した際に
エラーメッセージを表示させる機能作成しています。
ejsファイルに配列errorsを渡す実装中にエラーが発生しました。

先にsignファイル1で全く同じオブジェクト名やプロパティで実装できているファイルがあり
// ===================お客様使用============================================
// @-----------新規登録------------@
// ---ルーティング----
app.get('/signup',(req,res) => {
  res.render('signup.ejs',{errors:[]});
});
// ---ユーザー登録処理---
app.post('/signup',
  (req, res, next) => {
    console.log('入力値の空チェック');
    const username = req.body.nickname;
    const fullname = req.body.fullname;
    const password = req.body.password;
    const errors = [];

    if(username === ''){
      errors.push('ニックネームが空です');
    }
    if(fullname === ''){
      errors.push('フルネームが空です');
    }
    if(password === ''){
      errors.push('パスワードが空です');
    }
    console.log(errors);

    if(errors.length > 0){
      res.render('signup.ejs',{errors:errors})
    }else{
      next();
    }
  },
<!-- signファイル1 -->
<div class="sign">
      <div class="container">
        <h1><a href="/">BEAUTY APP</a></h1>
        <div class="panel">
          <h2>新規登録</h2>
          <% if (errors.length > 0) { %>
            <ul class="errors">

              <% errors.forEach(error => {%>
                <li><%= error %></li>
              <% }); %>
            </ul>
          <% } %>


signファイル1のファイルは動きます。
解決方法を教えて下さい。

発生している問題・エラー

express deprecated res.redirect(url, status): Use res.redirect(status, url) instead app.js:123:11
RangeError [ERR_HTTP_INVALID_STATUS_CODE]: Invalid status code: { errors: [Array] }
at ServerResponse.writeHead (_http_server.js:255:11)
    at ServerResponse.writeHead (/Users/**/Desktop/ノート/node_modules/on-headers/index.js:44:26)
    at ServerResponse._implicitHeader (_http_server.js:246:8)
    at write_ (_http_outgoing.js:685:9)
    at ServerResponse.end (_http_outgoing.js:798:5)
    at ServerResponse.end (/Users/**/Desktop/ノート/node_modules/express-session/index.js:359:19)
    at ServerResponse.redirect (/Users/**/Desktop/ノート/node_modules/express/lib/response.js:951:10)
    at /Users/**/Desktop/ノート/app.js:123:11
    at Layer.handle [as handle_request] (/Users/**/Desktop/ノート/node_modules/express/lib/router/layer.js:95:5)
    at next (/Users/**/Desktop/ノート/node_modules/express/lib/router/route.js:137:13)

該当するソースコード

// =========スタッフ使用===
// @-----------新規登録------------@
// ---ルーティング----
app.get('/staffsign',(req,res) => {
  res.render('staffsign.ejs',{errors:[]});
});
// ---ユーザー登録処理---
app.post('/staffsign',
  (req,res,next) => {
    console.log('ちぇっく');
    const staffnick = req.body.staffnick;
    const staffname = req.body.staffname;
    const staffpass = req.body.staffpass;
    const errors = [];

    if(staffnick === ''){
      errors.push('ユーザー名が空です');
    }
    if(staffname === ''){
      errors.push('メールアドレスが空です');
    }
    if(staffpass === ''){
      errors.push('パスワードが空です');
    }
    console.log(errors);

    if(errors.length > 0){
      res.redirect('/staffsign',{errors:errors});
    }else{
      next();
    }
  },
<!-- signファイル2 -->
<div class="sign">
      <div class="container">
        <h1><a href="/">BEAUTY APP</a></h1>
        <div class="panel">
          <h2>新規登録</h2>
          <% if (errors.length > 0) { %>
            <ul class="errors">
             <% errors.forEach(error => {%>
                <li><%= error %></li>
              <% }); %>
            </ul>
          <% } %>

自分で試したこと

・エラーコードの検索
→英語の記事が多く、1人では解決できる気がしなかったのでお力添えをお願いしたいです。
・ファイル2の定数のerrorserrrrなどに変更し、それに伴いif文を変えましたが、リファレンスエラーになるだけで解決できませんでした。

0

1Answer

エラーの読み解き方から順を追って説明します。

RangeError [ERR_HTTP_INVALID_STATUS_CODE]: Invalid status code: { errors: [Array] }
at ServerResponse.writeHead (_http_server.js:255:11)
    at ServerResponse.writeHead (/Users/**/Desktop/ノート/node_modules/on-headers/index.js:44:26)
    at write_ (_http_outgoing.js:685:9)
...

これは

エラークラス名: エラーの説明
at エラーを throw したクラス名.メソッド名 (エラーを throw したファイル名:行番号:列番号)
    at ↑のメソッドを呼び出したクラス名.メソッド名 (その呼び出しが書かれたファイル名:行番号:列番号)
    at ↑のメソッドを呼び出したクラス名.メソッド名 (その呼び出しが書かれたファイル名:行番号:列番号)
...

と読みます。エラーの発生箇所を探すには、 at 行を上から見ていって、ご自分で作られたファイル名を見つけてください。(目安として、スラッシュを含まないファイル名や /node_modules/ を含むファイル名はライブラリのコードなので読み飛ばせます。)

ご質問のエラーでは /Users/**/Desktop/ノート/app.js:123:11 ですね。つまり app.js の123行目で呼び出されたメソッドがエラーの引き金になっています。

      res.redirect('/staffsign',{errors:errors});

この行によって、

RangeError [ERR_HTTP_INVALID_STATUS_CODE]: Invalid status code: { errors: [Array] }

が引き起こされます。 { errors: 配列 } なる値は status code として不適切である、というエラーです。

意味が分からなければマニュアルを調べます。 res は Express ライブラリのコードなので、ここを見ます。 http://expressjs.com/ja/api.html#res.redirect

使い方が以下のように説明されています。 res.redirect() の最後の引数には path を与えるということです。

res.redirect([status,] path)

res.redirect(301, 'http://example.com')

path と status code は関係なさそうですが、ここでエラーメッセージを振り返ると、最初に以下の警告が出ています。

express deprecated res.redirect(url, status): Use res.redirect(status, url) instead app.js:123:11

res.redirect(url, status) の呼び出し方は古く、非推奨になったので、代わりに res.redirect(status, url) 使うように、とのことです。 今のところは古い呼び出し方でも動くようですね。

ここから、 res.redirect('/staffsign',{errors:errors}) でエラーが出るのは、第2引数を(古い挙動に従って) status として解釈しているからだということが分かります。

さて、いずれにしても、 res.redirect() は表示したいエラーメッセージ {errors:errors} を受け取れないことが分かります。リダイレクトはそういうものです。もしリダイレクト先に値を受け渡したいときは Express のセッションに格納するようにしてください。

それよりも、ここではリダイレクトを使う必要はありません。ファイル1と同じく res.render() を使って以下のように書けば動くと思います。

res.render('staffsign.ejs',{errors:errors})
1Like

Comments

  1. @yuka-f

    Questioner

    とても丁寧にわかりやすく助かりました。
    エクスプレスの学習を深めるとともに、エラー文読み解いたり、訳すなども慣れていけるようになろうと思えました^^
    ありがとうございました!

Your answer might help someone💌