JSONの取り回し
ファイルに入るのは文字だけ
ファイルに保存できるのは文字です。JavaScript の配列やオブジェクトを、そのまま置くことはできません。
そこで往復のたびに変換します。
| したいこと | 使うもの |
|---|---|
| 配列やオブジェクト → 文字列 | JSON.stringify |
| 文字列 → 配列やオブジェクト | JSON.parse |
書くときが stringify、読むときが parse です。方向を取り違えると、文字列に対して filter を呼ぶような、意味の通らないコードになります。
読みやすく保存する
JSON.stringify は既定では 1 行にまとめます。人が開いて確かめたいファイルなら、字下げを指定できます。
JavaScript
JSON.stringify(items, null, 2);3 つ目の 2 が字下げの幅です。2 つ目の null はここでは使いません。ファイルは少し大きくなりますが、中身を目で追えるようになります。
追加は読んでから書く
商品を 1 件足すときの流れは、前に触れたとおりです。
JavaScript
const raw = await fs.readFile(filePath, "utf8");
const items = JSON.parse(raw);
items.push(newItem);
await fs.writeFile(filePath, JSON.stringify(items, null, 2));読む・足す・書き戻す、の 3 段です。読まずに書くと、それまでの商品が消えます。
壊れたファイルに備える
JSON.parse は、渡された文字列が JSON として読めないとエラーを投げます。ファイルが空だったり、書き込みの途中で止まっていたりすると起こります。
JavaScript
let items;
try {
items = JSON.parse(raw);
} catch (error) {
items = [];
}こう書いておくと、読めなかったときに空の配列から始められます。エラーで止まるか、それとも続けられる形にするかは、その場で決める設計の判断です。ここでは「商品がまだ 1 件も無い状態」として扱うのが自然です。
手を動かす
演習では、ファイルに商品を 1 件追加します。読む・足す・書き戻す、の 3 段を自分で組み立ててください。初期コードは読む手順を飛ばしているので、そこが直すところです。
要件
- 受け取った
initialを JSON の文字列にして、受け取った場所へ書き込む - 書き込んだファイルを読み直し、JSON として解釈する
- 読み直した配列の末尾に
newItemを足し、ファイルへ書き戻したうえで、その配列を返す
入出力例
addItem("/tmp/fleama-add-a.json", [], {"id":1,"name":"レザースニーカー","price":4800}) → [{"id":1,"name":"レザースニーカー","price":4800}]
addItem("/tmp/fleama-add-b.json", [{"id":1,"name":"レザースニーカー","price":4800}], {"id":2,"name":"古着のデニムジャケット","price":6200}) → [{"id":1,"name":"レザースニーカー","price":4800},{"id":2,"name":"古着のデニムジャケット","price":6200}]
addItem("/tmp/fleama-add-c.json", [{"id":1,"name":"レザースニーカー","price":4800},{"id":2,"name":"古着のデニムジャケット","price":6200}], {"id":3,"name":"木製のスツール","price":3500}) → [{"id":1,"name":"レザースニーカー","price":4800},{"id":2,"name":"古着のデニムジャケット","price":6200},{"id":3,"name":"木製のスツール","price":3500}]ヒント
編集 ゆめさく編集部