質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

2回答

1471閲覧

htmlのformに入力した値をnode.jsで受け取りたい

yamamegumi

総合スコア3

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2021/08/22 12:06

前提・実現したいこと

htmlのformに入力した値をnode.jsで受け取りたい

TypeError: Cannot read property 'subject' of undefined at C:\Users\r.yama\Desktop\study_time.ver2.0\app.js:53:17 at Layer.handle [as handle_request] (C:\Users\r.yama\Desktop\study_time.ver2.0\node_modules\express\lib\router\layer.js:95:5) at next (C:\Users\r.yama\Desktop\study_time.ver2.0\node_modules\express\lib\router\route.js:137:13) at Route.dispatch (C:\Users\r.yama\Desktop\study_time.ver2.0\node_modules\express\lib\router\route.js:112:3) at Layer.handle [as handle_request] (C:\Users\r.yama\Desktop\study_time.ver2.0\node_modules\express\lib\router\layer.js:95:5) at C:\Users\r.yama\Desktop\study_time.ver2.0\node_modules\express\lib\router\index.js:281:22 at param (C:\Users\r.yama\Desktop\study_time.ver2.0\node_modules\express\lib\router\index.js:354:14) at param (C:\Users\r.yama\Desktop\study_time.ver2.0\node_modules\express\lib\router\index.js:365:14) at Function.process_params (C:\Users\r.yama\Desktop\study_time.ver2.0\node_modules\express\lib\router\index.js:410:3) at next (C:\Users\r.yama\Desktop\study_time.ver2.0\node_modules\express\lib\router\index.js:275:10)

該当のソースコード

javascript

1 <form action="/update/<%= studyTime.id %>" method="post"> 2 <input type="text" name="subject" value="<%= studyTime.subject %>" class='editTools'> 3 <input type="date" name="date" value="<%= y + '-' + m + '-' + d %>" class='editTools'> 4 <input type="time" name="time" value="<%= studyTime.time %>" class='editTools'> 5 <input type="submit" value="更新" class='editTools'> 6 </form> 7</body>

node

1app.post('/update/:id',(req,res)=>{ 2 connection.query( 3 'update users set subject = ?,date = ?,time = ? where id=?', 4 [req.body.subject,req.body.date,req.body.time,req.params.id], 5 (error,results)=>{ 6 res.redirect('/index'); 7 }); 8});

補足情報(FW/ツールのバージョンなど)

express version 4.17.1

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

TypeError: Cannot read property 'subject' of undefined

JavaScript(Node.js)はオブジェクト指向言語なので
object.propertyNameのように.を使う事でプロパティにアクセス出来ます。

しかし、プロパティを所持出来ない例外の値がJavaScriptには存在します。

  • undefined
  • null

これらの値に対してプロパティのアクセスを試みた時点でエラーで落ちます。

req.body.subject

エラー文を紐解くに、subjectがundefinedだから落ちているようです。
つまりreqの時点では普通にオブジェクトだった。

しかし、req.bodyというプロパティは存在せず、
存在しないプロパティを取り出すとJavaScriptではundefinedになってしまいます。
だからundefinedのプロパティアクセスによるエラー落ちとなってしまいました。

これに対応するなら
オプショナルチェイニング演算子を使って値を取り出しましょう。
そうすることで途中でundefined値になっても安全にプロパティにアクセスできます。

js

1app.post('/update/:id',(req,res)=>{ 2 connection.query( 3 'update users set subject = ?,date = ?,time = ? where id=?', 4 [req.body?.subject,req.body?.date,req.body?.time,req.params?.id], 5 (error,results)=>{ 6 res.redirect('/index'); 7 }); 8});

上記の回答を読んだ質問者さんは
「そうじゃねーよ!何でreq.bodyがundefinedになるんだよ!」となると思います。
これ解決せずにオプショナルチェイニング使ってundefinedが取れても何も嬉しくないでしょう。

express version 4.17.1

実はExpress.jsが何もしなくても自動的にreq.bodyを用意してくれる訳ではありません。
body-parserというライブラリを併用する前提で最初から作っているからです。

軽く経緯に触れると
そもそもブラウザから発射されるHTTPリクエストは単なる文字列です。
それのBody部分を解析して値を取り出すというのは普通に増えます。
Webサーバの負荷やパフォーマンスを考えると不要なら解析したくないんです。

そのへんの経緯でExpress.jsのかなり古いのバージョンで
body-parserライブラリは根幹部分から切り離されました。
そして使いたい時にミドルウェアとして挿し込んでくれみたいな運用に変更されました。


ではbody-parserの簡単な解説と
ミドルウェアの使い方を説明します。

bash

1# package.jsonファイルがあるディレクトリでnpmを使ってインストール 2$ npm install body-parser

使い方はbody-parserのページ下部にあるExamplesを読めば3つのケースで紹介されていますが
簡単にコードベースで記述します。

js

1const express = require('express'); 2const bodyParser = require('body-parser'); 3 4const app = express(); 5 6// この一文を足せばOK、ただし全てのURLでパースする事になる 7app.use(bodyParser.urlencoded({ extended: false })); 8 9app.post('/update/:id',(req,res)=>{ 10 connection.query( 11 'update users set subject = ?,date = ?,time = ? where id=?', 12 [req.body.subject,req.body.date,req.body.time,req.params.id], 13 (error,results)=>{ 14 res.redirect('/index'); 15 }); 16}); 17 18// 適当に3000番ポートで実行 19app.listen(3000);

ここから色々と工夫出来ますが
回答が無限に長くなるので参考記事を色々と貼って締めます。

body-parserは今回の質問にダイレクトに影響しますが、認証システムに欠かせないセッションやクッキーも切り離されてミドルウェア運用する前提なのは覚えておきましょう

ミドルウェアの扱い方が解説されています

投稿2021/08/22 13:28

編集2021/08/22 13:29
miyabi-sun

総合スコア21158

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yamamegumi

2021/08/25 07:51

そういう理屈だったんですね、、 参考記事までありがとうございます! 勉強させていただきました!
guest

0

自己解決

https://qiita.com/hirochan/items/e63d74cb70f0b97889fc

こちらを参考にbody-parserをインストールすることで動作しました

投稿2021/08/22 13:13

yamamegumi

総合スコア3

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問