前回の内容
前回は、商品更新ページの実装をしました↓
https://sakublog.tech/handson/express-app-4/
今回は商品を購入(削除)できるようにします。
実装方針
追加と更新はフォームで実装しましたが、今回はAjaxで実装します。
- 購入ボタン押下時、Expressで購入idを受け取る
- バリデーション
- 削除処理
以上のステップで実装します。
購入ボタン押下処理
まずidを受け取れるように、APIエンドポイントを作成します。
エンドポイントは/buy、deleteメソッドでアクセスするものとします。
idの受け取り方は追加、更新と同じ req.body です。
app.delete("/buy", async (req, res) => {
console.log(req.body.id);
// ここに削除処理を記述
});
一旦console.logで出力させるようにしました。
次に、フロントエンドから作成したAPIを呼び出します。
購入ボタンにイベントハンドラを追加しましょう。
headタグにスクリプトで関数を記述します。
<head>
<meta charset="UTF-8" />
<title>自動販売機アプリ</title>
<link rel="stylesheet" href="styles.css" />
<script>
function handleClickBuy(id) {
console.log(id);
}
</script>
</head>
とりあえず引数で受け取ったidをlogに出力します。
これを購入ボタンのonclickで呼び出します。
<button onclick="handleClickBuy('<%= drink.id %>')">購入</button>
この状態で、購入ボタンを押すと、コンソールに商品のidが表示されます。
ここまでできたら、APIを呼び出しましょう。
Fetchを使って、Ajax通信を行います。
今回はJSON形式でAPIをやりとりしたいので、ExpressでJSON
を受け取れるように設定します。
app.set("view engine", "ejs");
app.use(express.static("public"));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json()); // 追記
APIを呼び出してみます。
<script>
async function handleClickBuy(id) {
await fetch("/buy", {
method: "delete",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
id,
}),
});
window.location("/");
}
</script>
ポイントは2つです。
- リクエストheaderに“Content-Type”: “application/json”を指定
- JSON.stringifyでリクエストbodyをJSONにする
これでAPIにJSONでidをやりとりできます。
fetchが完了した後、window.locationでリロードしています。
実際に購入ボタンを押してみましょう。
コンソールにidが表示されました↓
バリデーション
今回は「idがなかったら何もさせない」というようにします。
app.delete("/buy", async (req, res) => {
if (!req.body.id) {
return;
}
// ここに削除処理を記述
idがリクエストbodyにない場合、returnしてあげればOKです。
削除処理
Delete文を発行して、レコードを消します。
プリペアドステートメントもこれまでと同様に記述できます。
app.delete("/buy", async (req, res) => {
if (!req.body.id) {
return;
}
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 = "DELETE FROM drinks WHERE id = ?";
await connection.query(sql, [req.body.id]);
await connection.end();
res.send("OK");
});
レスポンスは適当にOKと返却しておきます。
これで削除できるようになりました。
購入を押すと、
削除されました🙌
最後に
これで一通りの機能が完成しました!
お疲れ様でした!!
ここまでのコードはこちら↓
さらにブラッシュアップするとしたら、
- データベースの接続処理を共通化
- バリデーションに引っかかった際、以前の値を保持
- 追加や更新、削除時に成功のメッセージを表示
- SQLのエラーハンドリング
などがあります。
是非トライしてみてください!