【Node.js】Expressで作成したデータをJSONファイルで保存する
Node.js

【Node.js】Expressで作成したデータをJSONファイルで保存する

作成日:2021年10月25日
更新日:2021年10月25日

前回までは、データを配列にしてデータ内容を画面に表示していました。

今回は、データを JSON ファイルにしてから、データ内容を画面に表示します。

コードは、前回のコードを使用します。

nodejs-mvc-model

【Node.js】MVCに沿って、モデルを作成する

views/index.ejs

ejs
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title><%= pageTitle %></title>
</head>
<body>
<main>
<h1>メニュー</h1>
<p>メニュー一覧</p>
<% if(menus.length > 0) { for (let menu of menus){ %>
<p><%= menu.menuTitle %></p>
<%} %> <% } else { %>
<p>注文がありません</p>
<% } %>
</main>
</body>
</html>

views/menu.ejs

ejs
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="/css/styles.css" />
<title><%= pageTitle %></title>
</head>
<body>
<main>
<form action="/menu" method="POST">
<input type="text" name="title" />
<button type="submit">メニューを追加する</button>
</form>
</main>
</body>
</html>

index.js

js
const express = require("express");
const app = express();
const path = require("path");
app.set("view engine", "ejs");
app.set("views", "views");
const menuRoutes = require("./routes/index.js");
const menus = require("./routes/menu.js");
app.use(express.urlencoded({ extended: true }));
app.use(express.static(path.join(__dirname, "public")));
app.use("/", menus);
app.use(menuRoutes);
app.use((req, res, next) => {
res.status(404).send("<h1>ページが見つかりません</h1>");
});
app.listen(8000, () => console.log("Server is running ..."));

routes/index.js

js
const express = require("express");
const router = express.Router();
const menuController = require("../controllers/menus");
router.get("/", menuController.getAddMenus);
module.exports = router;

routes/menu.js

js
const express = require("express");
const router = express.Router();
const menuController = require("../controllers/menus");
router.get("/menu", menuController.getAddMenu);
router.post("/menu", menuController.postAddMenu);
module.exports = router;

controllers/menus.js

js
const Menu = require("../models/menu");
exports.getAddMenu = (req, res, next) => {
res.render("menu", { pageTitle: "メニュー追加" });
};
exports.postAddMenu = (req, res, next) => {
const menu = new Menu(req.body.title);
menu.save();
res.redirect("/");
};
exports.getAddMenus = (req, res, next) => {
const menus = Menu.fetchAll();
res.render("index", {
pageTitle: "メニュー一覧",
menus,
});
};

models/menu.js

js
const menus = [];
module.exports = class Menu {
constructor(title) {
this.menuTitle = title;
}
save() {
menus.push(this);
}
static fetchAll() {
return menus;
}
};

まず、JSON ファイルを使用するので、ファイルシステムを呼び出します。

js
const fs = require("fs");

次に、メニューデータの JSON ファイルを格納する場所を指定したいので、path を呼び出します。

js
const path = require("path");

メニューデータの JSON ファイルを格納する場所を指定します。

今回は、data フォルダの menus.json に格納するようにします。

Menu クラスの save のmenus.push(this);を一旦削除します。

ルートディレクトリ、data、menus.json のパスを join で繋げましょう。

js
const menuPath = path.join(
path.dirname(require.main.filename),
"data",
"menus.json"
);

メニューを読み取るために、ファイルシステムの readFile を使います。

js
save() {
const menuPath = path.join(
path.dirname(require.main.filename),
"data",
"menus.json"
);
fs.readFile();
}

readFile の中に、JSON のパスと処理内容を入力します。

js
save() {
const menuPath = path.join(
path.dirname(require.main.filename),
"data",
"menus.json"
);
fs.readFile(menuPath, (err, fileContent) => {
});
}

空の menus の配列を作成します。

js
fs.readFile(menuPath, (err, fileContent) => {
let menus = [];
});

ファイルの中身が null ではない場合、JSON を呼び出すようにします。

js
fs.readFile(menuPath, (err, fileContent) => {
let menus = [];
if (!err) {
menus = JSON.parse(fileContent);
}
});

menus の配列にデータを入れるようにします。

js
fs.readFile(menuPath, (err, fileContent) => {
let menus = [];
if (!err) {
menus = JSON.parse(fileContent);
}
menus.push(this);
});

menus.json にデータを変換して書き込むように設定します。

また、エラーが発生した際のエラーメッセージも設定しておきましょう。

js
fs.readFile(menuPath, (err, fileContent) => {
let menus = [];
if (!err) {
menus = JSON.parse(fileContent);
}
menus.push(this);
fs.writeFile(menuPath, JSON.stringify(menus), (err) => {
console.log(err);
});
});

一度、ブラウザで確認します。

image2

image3

メニューの追加した後の設定は、まだ行っていないのでエラーになりますが、menus.json にはデータを確認することができました。

次は、メニューの追加した後の画面設定を行いましょう。

Menu クラスのfetchAllreturn menus;を削除します。

saveの場合と同様に、メニューのパスの変数を作成します。

js
static fetchAll() {
const menuPath = path.join(
path.dirname(require.main.filename),
"data",
"menus.json"
);
}

ファイルシステムでファイルを読み込みます。

js
static fetchAll() {
const menuPath = path.join(
path.dirname(require.main.filename),
"data",
"menus.json"
);
fs.readFile(menuPath, (err, fileContent) => {
});
}

fetchAllにデータが渡るようにします。

エラーの場合は空の配列、エラーでない場合は、menus.json のファイルを読み取るようにします。

js
static fetchAll(data) {
const menuPath = path.join(
path.dirname(require.main.filename),
"data",
"menus.json"
);
fs.readFile(menuPath, (err, fileContent) => {
if (err) {
data([]);
}
data(JSON.parse(fileContent));
});
}

controllers フォルダの menus.js を開きます。

getAddMenusで Menu クラスのfetchAllmenusを返すようにします。

js
exports.getAddMenus = (req, res, next) => {
Menu.fetchAll((menus) => {
res.render("index", {
pageTitle: "メニュー一覧",
menus,
});
});
};

ブラウザで確認すると、

image4

image5

image6

メニューを追加すると、正しく画面が遷移されました。

json ファイルを確認すると、

image7

前回入力したデータに、先程入力されたデータが追加されました。

© 2024あずきぱんウェブスタジオ