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

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

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

EJSは、JavaScript用のテンプレートエンジン。HTMLなどのテンプレートテキストにJavaScriptのロジックを記述することができます。また、変数・関数の実行をテンプレートテキスト内に埋め込むことも可能です。

foreach

foreachは、List・Collection・Arrayといったデータ構造の各要素に対して繰り返し処理を実行するために扱われる、制御構造の構文です。

Node.js

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

Q&A

解決済

1回答

2569閲覧

【node.js】forEachで回した要素から、それぞれのformで値を送信したい

shibachi

総合スコア19

EJS

EJSは、JavaScript用のテンプレートエンジン。HTMLなどのテンプレートテキストにJavaScriptのロジックを記述することができます。また、変数・関数の実行をテンプレートテキスト内に埋め込むことも可能です。

foreach

foreachは、List・Collection・Arrayといったデータ構造の各要素に対して繰り返し処理を実行するために扱われる、制御構造の構文です。

Node.js

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

0グッド

0クリップ

投稿2020/10/12 09:13

編集2020/10/12 09:26

forEachで回した、それぞれのformから値を送信したい

node.jsを使って、簡単なsnsのwebアプリを開発しています。
「いいね」機能を実装中に以下のエラーメッセージが発生しました。

発生している問題・エラーメッセージ

TypeError: C:\xampp\htdocs\sns_app\views\main.ejs:26 24| <a href="/new_tweet">新規追加</a> 25| <ul> >> 26| <% tweets.forEach((tweet) => { %> 27| <li class="tweet"> 28| <span class="tweet_id"><%= tweet.id %></span> 29| <span class="tweet_content"><%= tweet.content %></span> Cannot read property 'forEach' of undefined at eval (C:\xampp\htdocs\sns_app\views\main.ejs:15:15) at main (C:\xampp\htdocs\sns_app\node_modules\ejs\lib\ejs.js:691:17) at tryHandleCache (C:\xampp\htdocs\sns_app\node_modules\ejs\lib\ejs.js:272:36) at View.exports.renderFile [as engine] (C:\xampp\htdocs\sns_app\node_modules\ejs\lib\ejs.js:489:10) at View.render (C:\xampp\htdocs\sns_app\node_modules\express\lib\view.js:135:8) at tryRender (C:\xampp\htdocs\sns_app\node_modules\express\lib\application.js:640:10) at Function.render (C:\xampp\htdocs\sns_app\node_modules\express\lib\application.js:592:3) at ServerResponse.render (C:\xampp\htdocs\sns_app\node_modules\express\lib\response.js:1012:7) at Query.connection.query (C:\xampp\htdocs\sns_app\app.js:69:13) at Query.<anonymous> (C:\xampp\htdocs\sns_app\node_modules\mysql\lib\Connection.js:526:10)

該当のソースコード

EJS

1<ul> 2 <% tweets.forEach((tweet) => { %> 3 <li class="tweet"> 4 <span class="tweet_id"><%= tweet.id %></span> 5 <span class="tweet_content"><%= tweet.content %></span> 6 <% 7 var category; 8 var list =["恋愛","科学","仕事","日常","広告","PC","病院","漫画","映画","ゲーム","政治"]; 9 category = list[tweet.category]; 10 %> 11 <span class="category">#<%= category %></span> 12 <form action="update_good" method="post"> 13 <input type="hidden" name="tweet_id" value="<%= tweet.id %>"> 14 <input type="submit" value="<%= tweet.good %>"> 15 </form> 16 </li><!--tweet--> 17 <% }); %> 18 </ul>

該当のソースコード

node.js

1//mainページの表示 2app.get('/main', (req, res) => { 3 connection.query( 4 'SELECT * FROM tweets', 5 (error,results)=>{ 6 res.render('main.ejs',{user:username,tweets:results}); 7 }); 8}); 9//イイねボタンの更新 10app.post('/update_good', (req, res) => { 11 connection.query( 12 'UPDATE tweets SET good WHERE id=?', 13 [req.body.tweet_id], 14 (error,results)=>{ 15 res.render('main.ejs',{user:username,tweets:results}); 16 }); 17});

試したこと

送信ボタンを押すと、このようなエラーを吐き出します。
表示をするだけなら、問題なくできております。

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

"dependencies": {
"ejs": "^3.1.5",
"express": "^4.17.1",
"jquery": "^3.5.1",
"mysql": "^2.18.1"
}

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

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

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

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

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

guest

回答1

0

ベストアンサー

Cannot read property 'forEach' of undefined

このエラー文は頻出なので覚えましょう。
まずはエラー文が何者なのかを説明します。

JSはオブジェクト指向プログラミング言語なので、
値はオブジェクトです。
オブジェクトはプロパティを所持することが許されています。

しかし、JSではプロパティの所持を許されていない
例外中の例外の値が2つ存在します

  • null
  • undefined

これらはプロパティの所持を許されていないどころか、
参照を試みただけでエラーで落ちてしまいます。
それがこのエラー。


さて、今回の質問を深堀りしましょう。

今回のエラー文を読み解きましょうか。
Cannot read property 'forEach' of undefinedでしたっけ。
なので直訳すればundefinedforEachプロパティを参照しようとしたのでエラー。

forEachがあるのはtweets.forEachの行ですね。
tweetsは配列であるべきだったのにundefinedが入っている事が問題です。
なぜtweetsが配列でないのか?に着目し、より上流の箇所を修正しましょう。

そういや「いいねボタン」押した時の挙動がおかしいんでしたっけ?
どれどれ?

js

1//イイねボタンの更新 2app.post('/update_good', (req, res) => { 3 connection.query( 4 'UPDATE tweets SET good WHERE id=?', 5 [req.body.tweet_id], 6 (error,results)=>{ 7 res.render('main.ejs',{user:username,tweets:results}); 8 }); 9});

'UPDATE tweets SET good WHERE id=?'のSQL文を送った結果がどうなるのか確認してみましたか?
これはUPDATEの結果テーブルがどうなったかの結果が得られるはずです。
tweetsテーブルの値の配列が入っているはずがないんですよ。

UPDATEに成功したら改めてSQLのSELECTを発行し
SELECTの結果をtweetsに束縛して使いましょう。

まぁこういったWebサーバを実装する上で、
Postの結果でHTMLを返す作りにするとF5キーでリロードする度にPostの処理が走るので微妙です。
リダイレクトさせるのが常套手段ですね。

Expressのリダイレクト機能を使って/パスのgetにリクエストを受け流す実装に変更しましょう。

投稿2020/10/12 09:44

編集2020/10/12 09:56
miyabi-sun

総合スコア21158

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

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

shibachi

2020/10/12 10:19

redirectに修正すると、直りました! ご丁寧にありがとうございました!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問