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

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

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

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

Node.js

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

セッション

Sessionはクライアントがサーバに送ったすべてのリクエストのことを指します。

ログイン

ログインは、ユーザーがコンピューターシステムにアクセスするプロセスの事を呼びます。

Express

ExpressはNode.jsのWebアプリケーションフレームワークです。 マルチページを構築するための機能セットおよびハイブリッドのWebアプリケーションを提供します。

Q&A

解決済

1回答

1547閲覧

Node.js+Expressでログイン機能がうまく作れない

dydo

総合スコア8

EJS

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

Node.js

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

セッション

Sessionはクライアントがサーバに送ったすべてのリクエストのことを指します。

ログイン

ログインは、ユーザーがコンピューターシステムにアクセスするプロセスの事を呼びます。

Express

ExpressはNode.jsのWebアプリケーションフレームワークです。 マルチページを構築するための機能セットおよびハイブリッドのWebアプリケーションを提供します。

0グッド

1クリップ

投稿2019/09/05 06:15

前提・実現したいこと

Node.js(v10.15.3)+Expressでチャットアプリを作っています。
テンプレートはejsを使用しています。
ログイン後にホーム画面にユーザー名と友達リストを表示したいのですが、うまく友達リストが取得できません。変数やメソッドの位置に問題があるようですが、検索してもよくわかりませんでした。
よろしくおねがいします。

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

エラーメッセージはないが、postsで友達リストが取得できてないないらしく、表示されない。 ・ユーザー名はejsファイルに正常に表示される  <p><%= login.name %></p> ・友達リストは繰り返して表示 <% for(var i in posts) { %> <% var obj = posts[i]; %> <li class="contact"> <div class="wrap"> <img src="<%= obj.icon %>" alt="" /> <div class="meta"> <p class="name"><%= obj.name %></p> <p class="preview"><%= obj.comment %></p> </div> </div> </li>

該当のソースコード

javascript、node.js、express

1 2var express = require('express'); 3var router = express.Router(); 4 5//友達一覧のレコード 6var posts = []; 7 8var mysql = require('mysql') 9var connection = mysql.createConnection({ 10 host: 'localhost', 11 user: 'root', 12 password: '*****', 13 database: 'msgapp3', 14 insecureAuth: true 15}); 16 17//フレンドリストの取得1 18//ここに書いた場合、きちんと友達リストが表示されるが、 19//本来はセッションからidを取得したいのでif文の後に書きたい 20/* 21connection.connect() 22sql = 'select name, icon, comment from users inner join f_relation on users.id = f_relation.friend_id where f_relation.user_id = ?;'; 23var id = 'aaa';//仮に 24connection.query(sql, id, function (err, rows, fields) { 25 if (err) throw err 26 //postsにレコードを代入 27 posts = rows; 28}) 29connection.end() 30*/ 31 32//セッションがなければログイン画面に遷移 33router.get('/', (req, res, next) => { 34 if (req.session.login == null) { 35 res.redirect('/users'); 36 return 37 } else { 38 //セッションがある場合、メイン画面にユーザー名と友達リストを表示したい 39 //フレンドリストの取得2 40 connection.connect() 41 sql = 'select name, icon, comment from users inner join f_relation on users.id = f_relation.friend_id where f_relation.user_id = ?;'; 42 var id = 'aaa';//仮に 43 connection.query(sql, id, function (err, rows, fields) { 44 if (err) throw err 45 //postsにレコードを代入 46 posts = rows; 47 }) 48 connection.end() 49 res.render('index', { login: req.session.login, posts}); 50 } 51}); 52 53module.exports = router; 54

試したこと

友達リストの取得位置を変えると正常に動作する。
2つの位置で何が違うのかわからない。
セッションからIDを取得する方法もわからない。

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

Node.js v10.15.3
Expressを使用

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

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

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

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

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

guest

回答1

0

ベストアンサー

処理順がわかるように

JavaScript

1const mysql = require('mysql'); 2const connection = mysql.createConnection({ 3 host : '192.168.33.11', 4 user : 'test', 5 password : '****' 6}); 7 8connection.query(` 9 SELECT * 10 FROM \`master\`.\`hoge\` 11 WHERE \`id\` = 1072353 12 `, function (error, results, fields) { 13 if(error) { 14 console.log(error); 15 } 16 else { 17 console.log(results); 18 console.log('2'); 19 } 20 } 21) 22connection.end(); 23console.log('1');

というプログラムを動かすと
1
console.log(results)の内容
2
とでます。この理由はconnection.queryが非同期処理(コールバック処理)のためです。
ので

JavaScript

1 //postsにレコードを代入 2 posts = rows;

の直後にres.render('index', { login: req.session.login, posts});を呼ぶべきです

追記

JavaScript

1// express 2const express = require('express'); 3const app = express(); 4 5// mysql 6const mysql = require('mysql'); 7const connection = mysql.createConnection({ 8 host : '192.168.33.11', 9 user : 'hoge', 10 password : 'hoge' 11}); 12 13// 結果 14let posts = []; 15 16var server = app.listen(3000, function(){ 17 console.log("Node.js is listening to PORT:" + server.address().port); 18}); 19 20app.get('/', function(req, res, next) { 21 connection.query(` 22 SELECT * 23 FROM \`master\`.\`hoge\` 24 WHERE \`id\` = ?; 25 `, 1072353, function (error, results, fields) { 26 if(error) { 27 console.log(error); 28 } 29 else { 30 posts = results; 31 console.log(results); 32 res.json(results); 33 } 34 } 35 ); 36});

connection.connect()connection.end()を入れると複数回アクセスでエラー出るので処理をなくすと動くのは確認しました

投稿2019/09/06 02:09

編集2019/09/06 03:48
rururu3

総合スコア5545

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

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

dydo

2019/09/06 02:39

回答ありがとうございます。 非同期処理のために先に後の処理がされているということですね。参考になります。 res.render('index', { login: req.session.login, posts }); の位置を変更しました。 しかし、それでもうまくいきませんでした。 確認してみたところ、 1の位置だとrowsはきちんと配列の中身が表示されるのですが、 2のif文の後だとrowsが空になっていることがわかりました。 なぜでしょうか。 //セッションがなければログイン画面に遷移 router.get('/', (req, res, next) => { if (req.session.login == null) { res.redirect('/users'); return } else { //セッションがある場合、メイン画面にユーザー名と友達リストを表示したい //フレンドリストの取得2 connection.connect() sql = 'select name, icon, comment from users inner join f_relation on users.id =  f_relation.friend_id where f_relation.user_id = ?;'; var id = 'aaa';//仮に connection.query(sql, id, function (err, rows, fields) { if (err) throw err console.log(rows)//確認するとこの段階で空になっている、なぜ? //postsにレコードを代入 posts = rows;// res.render('index', { login: req.session.login, posts }); }) connection.end() } });
rururu3

2019/09/06 02:48

expressでちょっと試してみます(connection周りが原因な気がする
dydo

2019/09/09 00:38

ありがとうございました。
dydo

2019/09/09 04:31 編集

router.get('/', (req, res, next) => { if (req.session.login == null) { res.redirect('/users'); return } else { //フレンドリストの取得 connection.connect() sql = 'select name, icon, comment from users inner join f_relation on users.id = f_relation.friend_id where f_relation.user_id = ?;'; var id = 'aaa'; connection.query(sql, id, function (err, rows, fields) { if (err) throw err //postsにレコードを代入 posts = rows; res.render('index', { login: req.session.login, posts }); }) } connection.end() }); すみません。 やはり問題は最初に解答頂いた内容で合っていたようです。 処理の順番が問題だったんですね。 週明けに改めて書いてみたところ、解決しました。 1.postsの直後にrenderメソッドを書く、 2.connection.end()を外側のカッコに移す。 回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問