Expressで作るアプリ開発入門 一覧実装編

Express

前回の内容

前回は、環境構築まで行いました。

前回の記事はこちら

今回は一覧画面を作成していきます。

テーブルの作成

テーブル設計

drinksテーブルを作成します。

カラムと制約は下記のようにします。

  • id 主キー
  • name 必須、255文字以内
  • price 0以上の整数
  • temperature 0か1   1はあったかい、0はつめたいにします。

テーブル作成

TablePlusやphpMyAdminなどのDBクライアントで、CREATE TABLE文を実行します↓

CREATE TABLE drinks (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    price INT UNSIGNED NOT NULL,
    temperature TINYINT(1) NOT NULL -- 1:あったかい 0:つめたい
);

実行すると、drinksテーブルができています↓

サンプルデータの投入

INSERT文で、データを10件登録します。

INSERT INTO drinks (name, price, temperature)
VALUES 
    ('コーヒー', 250, 1),
    ('アイスティー', 200, 0),
    ('ホットチョコレート', 300, 1),
    ('レモネード', 180, 0),
    ('紅茶', 220, 1),
    ('オレンジジュース', 150, 0),
    ('緑茶', 200, 1),
    ('アイスコーヒー', 230, 0),
    ('カフェラテ', 280, 1),
    ('アイスカフェラテ', 260, 0);

drinksテーブルに、データが入りました↓🥳

データベースに接続

次に、一覧ページアクセス時にデータベースに接続します。

まず、npmでmysqlに接続するためのライブラリを入れます。

mysql2
fast mysql driver. Implements core protocol, prepared statements, ssl and compression in native JS. Latest version: 3.7.0, last published: 8 hours ago. Start us...
npm i mysql2

package.jsonのdependenciesにmysql2が入りました↓

次にExpressからMySQLに接続するのですが、その前に環境変数に接続情報を記述します。

.envファイルを作成し、

touch .env

.gitignoreに.envを追加して、機密情報の流出を防ぎます(gitにあげてはならない。超重要!!

node_modules 
.env

.envに接続情報を記述します。

続いて、環境変数を読み込むためのライブラリをインストールします。

dotenv
Loads environment variables from .env file. Latest version: 16.3.1, last published: 7 months ago. Start using dotenv in your project by running `npm i dotenv`. ...
npm i dotenv

.envファイルから接続情報を読み込んでみます。

dotenvをimportし、.envに書いた内容が読み取れるか確認します。

node app.js

でサーバーを立ち上げ、

http://localhost:3000/

にアクセスすると、

ターミナルにMYSQL_HOSTの値が表示されました!

では、実際にMySQLに接続します。app.jsをこのように変更します↓

import express from "express";
import mysql from "mysql2/promise";
import "dotenv/config";
const app = express();
const port = 3000;


app.set("view engine", "ejs");


app.use(express.static("public"));


app.get("/", async (req, res) => {
  const connection = await mysql.createConnection({
    host: process.env.MYSQL_HOST,
    database: process.env.MYSQL_DATABASE,
    user: process.env.MYSQL_USER,
    password: process.env.MYSQL_PASSWORD,
  });
  console.log(connection.config.user);
  res.render("index");
});


app.get("/add", (req, res) => {
  res.render("add");
});


app.get("/update", (req, res) => {
  res.render("update");
});


app.listen(port, () => {
  console.log(`Example app listening on port ${port}`);
});

async-awaitを用いて記述していきます。

createConnectionメソッドで、データベースに接続ができます。

connection.config.user

で、接続したユーザー名がターミナルに表示されればOKです。

再度node app.js

を実行し、トップページにアクセスします。

ターミナルに、ユーザー名が表示されました。

接続できました🙌

エラーが出て接続できない時は、再度データベースの接続情報が正しいか、これまでの手順に間違いがないかご確認ください。

飲み物の一覧を取得する

実際にSQLでdrinksテーブルの一覧を取得してみます。

app.jsのトップページ部分の実装を修正します。

app.get("/", async (req, res) => {
  const connection = await mysql.createConnection({
    host: process.env.MYSQL_HOST,
    database: process.env.MYSQL_DATABASE,
    user: process.env.MYSQL_USER,
    password: process.env.MYSQL_PASSWORD,
  });
  const sql = "SELECT * FROM drinks";
  const result = await connection.execute(sql); // SQLを発行
  console.log(result); // 結果を表示
  await connection.end(); // dbと接続切る
  res.render("index");
});

こちらで、トップページにアクセスしてターミナルを確認すると、

配列形式で、drinksテーブルの内容が取得できました!

配列の0番目にINSERTした内容、1番目にテーブル定義の内容が入っています。

0番目result[0]を取得して、viewに渡せば良さそうですね。

取得結果をviewに渡す

app.jsの変数をejsに渡すには、

res.render("index", { ejsで受け取る変数名: 渡す変数 });

の形式で渡します。

res.renderの第二引数に、オブジェクトの形式で渡せばOKです!

app.jsのトップページの実装を次のように変更します。

app.get("/", async (req, res) => {
  const connection = await mysql.createConnection({
    host: process.env.MYSQL_HOST,
    database: process.env.MYSQL_DATABASE,
    user: process.env.MYSQL_USER,
    password: process.env.MYSQL_PASSWORD,
  });
  const sql = "SELECT * FROM drinks";
  const result = await connection.execute(sql);
 await connection.end();
  res.render("index", { drinks: result[0] }); // 取得結果を第二引数で渡すように変更
});

そしてindex.ejs側で受け取ってみます。

ejsでは

<% %>

の間に、Javascriptのコードを記述することができます。

下記をindex.ejsの適当な位置に入れて下さい。

<% console.log(drinks); %>

drinksの値が取れているか、デバッグします。

再度サーバーを立ち上げ、トップページにアクセスします。

ターミナルに、値が表示されればOKです!

飲み物の表示

名前、値段の表示

次に、実際の画面に反映していきます。

forEachを使ってループ処理させます。

Array.prototype.forEach() - JavaScript | MDN
forEach() メソッドは、与えられた関数を、配列の各要素に対して一度ずつ実行します。

index.ejsのulタグの箇所を書き換えます↓

      <!-- 商品のリスト -->
      <ul class="products">
        <% drinks.forEach((drink)=>{ %>
        <li class="product">
          <h2 class="product-name">
            <a class="product-link" href="#"><%= drink.name %></a>
          </h2>
          <p class="product-price">¥<%= drink.price %></p>
          <p class="product-temperature warm"><%= drink.temperature %></p>
          <button>購入</button>
        </li>
        <% }) %>
      </ul>

この状態で、再度トップページにアクセスします。

データベースに投入した内容が表示されました!!!

ejsのコードを解説すると、

<% drinks.forEach((drink)=>{ %>

のところでループ処理が走ります。

<% %>の中は従来のJavascriptと変わりありません。

<%= drink.name %>

のところで、forEachでループしている1つ1つが表示されています。

<%= %>

は、値を表示させるのに使用します。

あたたかいの表示

あたたかいorつめたいの表示も実装します。

ここでは三項演算子を使って、条件分岐させます。

          <p
            class="product-temperature <%= drink.temperature ? 'warm' :'cold' %>"
          >
            <%= drink.temperature ? "あたたかい" :"つめたい" %>
          </p>

drink.temperature

は1か0が入ります。

Javascriptの暗黙的な型変換で、1はtrue、0はfalseとみなされます。

これを利用し、

<%= drink.temperature ? "あたたかい" :"つめたい" %>

で出し分けることができました!

classのところも同じように条件分岐させ、赤か青の色を出し分けています。

これで一覧表示は完成です!🎊