はいさい!オースティンやいびーん。月曜日、にりーよね。
概要
Window.localStorage
にオブジェクトを保存する方法を紹介します。
背景
Window.localStorageにJavaScriptのオブジェクトを丸ごと保存したいことがありますが、その時に以下のようなコードを実行してみますと、
window.localStorage.setItem("chura", { data: "ちゅら" })
window.localStorage.getItem("chura") // '[object Object]'
ご予想の通り、'[object Object]'
が返ってきます!アキサミヨー。
実は、Window.localStorage.setItem
は、数字、文字列、オブジェクト、何もかもUTF-16
に変換した上で、Window.localStorage
に保管するようになっているのです。
つまり、数字を保管した場合でも、Window.localStorage.getItem
で取り出したときには文字列になっているのです。
オブジェクトをそのまま渡した場合は、Object.prototype.toString
が実行され、今回の場合、オブジェクト名を設定していないので、デフォルトの'[object Object]'
が返ってきているのです。
解決法
オブジェクトを一旦、JSONに変換した上で、Window.localStorage.setItem
を実行するようにします!
const churadaNoData = { chura: "ちゅら" };
const churaNoJSONData = JSON.stringify(churaNoData);
window.localStorage.setItem("chura", churaNoJSONData);
そして取り出す時には以下のようにします。
const retrievedChuraNoData = JSON.parse(window.localStorage.getItem("chura"));
注意
JSONには関数を変換することができませんので、ご注意ください。
以下のようなコードを実行してみると、
const churadaNoData = { chura: "ちゅら", func: () => {} };
const churaNoJSONData = JSON.stringify(churaNoData);
window.localStorage.setItem("chura", churaNoJSONData);
JSON.parse(window.localStorage.getItem("chura")); // { chura: "ちゅら" }
func
は取り出されたオブジェクトにないことがわかります。
なぜなら、関数は、シリアライズが不可能だからです。
もっといいAPI:IndexedDB
実は、Objectをシリアル化できるブラウザの保存機能があります。
それは、**IndexedDB**です。
IndexedDBの使い方はLocal StorageおよびSession Storageより複雑なのでLocal Storageと同様に使いたい、Indexed DBの他の機能はいらないという場合はidb-keyval
というnpmパッケージを使うことを推奨します。
使い方は同様に簡単になります。
import { set } from 'idb-keyval';
set('obj', { a: 1 });
File System Access APIのFileHandleもIndexedDBに入れて設定を保存することができるのでIndexedDBもぜひ活用していただければと思います!
まとめ
localStorageにオブジェクトを保管する方法を紹介しましたが、いかがでしょうか?
こうすることで、オブジェクト形式で保存するとともに、オブジェクトの値を型を保持することもできます。