質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

878閲覧

indexedDBで2つのキーを同時に抽出したい

tajix_japan

総合スコア132

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2018/01/01 11:35

下記のようなindexedDBを組みました。

dbName = 'mydb';
storeName = 'mystore';
keyValue = 'MYID';YAMADA
keyValue = 'PASS';1234

下記のようにすることで、
<a href='./../index.html?uid=YAMADA'>インデックス</a>

というリンクを張ることができました。

javascript

1 2 3<!DOCTYPE html> 4<html> 5<head> 6 <meta charset="utf-8"/> 7 <title>Indexed DataBase APIサンプル</title> 8<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> 9</head> 10<body> 11 12<script> 13var dbName = 'mydb'; 14var openReq = indexedDB.open(dbName); 15// DB名を指定して接続。DBがなければ新規作成される。 16 openReq.onupgradeneeded = function(event){ 17 //onupgradeneededは、DBのバージョン更新(DBの新規作成も含む)時のみ実行 18 console.log('db upgrade'); 19 } 20 openReq.onsuccess = function(event){ 21 //onupgradeneededの後に実行。更新がない場合はこれだけ実行 22 console.log('db open success'); 23 var db = event.target.result; 24 // 接続を解除する 25 db.close(); 26 } 27 openReq.onerror = function(event){ 28 // 接続に失敗 29 console.log('db open error'); 30 } 31var storeName = 'mystore'; 32var keyValue = 'MYID'; 33var openReq = indexedDB.open(dbName); 34 openReq.onsuccess = function(event){ 35 var db = event.target.result; 36 var trans = db.transaction(storeName, 'readonly'); 37 var store = trans.objectStore(storeName); 38 var getReq = store.get(keyValue); 39 getReq.onsuccess = function(event){ 40 if (event.target.result === undefined) { 41 result.innerHTML = "指定したキーは存在しません。"; 42 } else { 43 result.innerHTML ="<a href='./../index.html?uid=" + event.target.result.myvalue + ""'>インデックス</a>"; 44 } 45 46 } 47 } 48</script> 49 50 51 52<BR>上部表示 53<BR> 54<div id="result"/> 55<BR> 56下部表示 57<BR> 58 59</body> 60</html> 61

今回やりたいこと

<a href='./../index.html?uid=YAMADA&pass=1234'>インデックス</a>

とユーザーIDだけでなくパスワードまでリンクにしたいと考えています。
(実際にはパスワードはSHA256化してます)

javascript

1var storeName = 'mystore'; 2var keyValue = 'MYID'; 3var openReq = indexedDB.open(dbName); 4 openReq.onsuccess = function(event){ 5 var db = event.target.result; 6 var trans = db.transaction(storeName, 'readonly'); 7 var store = trans.objectStore(storeName); 8 var getReq = store.get(keyValue); 9 getReq.onsuccess = function(event){ 10 if (event.target.result === undefined) { 11 result.innerHTML = "指定したキーは存在しません。"; 12 } else { 13 result.innerHTML ="<a href='./../index.html?uid=" + event.target.result.myvalue + ""'>インデックス</a>"; 14

の部分を「IDとPASSの2階建て」にすれば簡単に行けそうでしたので、下記のように書き換えました。

javascript

1var storeName = 'mystore'; 2 3var keyValue = 'MYID'; 4var keyValue2 = 'PASS'; 5 6var openReq = indexedDB.open(dbName); 7 openReq.onsuccess = function(event){ 8 9 var db = event.target.result; 10 var trans = db.transaction(storeName, 'readonly'); 11 var store = trans.objectStore(storeName); 12 var getReq = store.get(keyValue); 13 14 var db2 = event.target.result2; 15 var trans2 = db2.transaction(storeName, 'readonly'); 16 var store2 = trans2.objectStore(storeName); 17 var getReq2 = store2.get(keyValue2); 18 19 getReq.onsuccess = function(event){ 20 if (event.target.result === undefined) { 21 result.innerHTML = "指定したキーは存在しません。"; 22 } else { 23 result.innerHTML ="<a href='./../index.html?uid=" + event.target.result.myvalue + "&pws=" + event.target.result2.myvalue + "'>インデックス</a>"; 24

var keyValue2 = 'PASS';に対応する部分として

新たに

var db2 = event.target.result2; var trans2 = db2.transaction(storeName, 'readonly'); var store2 = trans2.objectStore(storeName); var getReq2 = store2.get(keyValue2);

を付け加え、リンクを
<a href='./../index.html?uid=" + event.target.result.myvalue + "&pws=" + event.target.result2.myvalue + "'>インデックス</a>"
としたものです。

結果

Uncaught TypeError: Cannot read property 'transaction' of undefined

というエラーが出ました。

次にresult2ではなくtarget2も試してみましたが、

event.target.result2; → 
var db2 = event.target2.result; に変更し
<a href='./../index.html?uid=" + event.target.result.myvalue + "&pws=" + event.target2.result.myvalue + "'>とする。

Uncaught TypeError: Cannot read property 'result' of undefined

というエラーが出ました。

どうすれば
<a href='./../index.html?uid=YAMADA&pass=1234'>インデックス</a>
のようにIDとパスワードを引っ張ってくることができるのでしょうか?

よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

どのようにストアを作成しているのかがかかわってくると思うのですが、
例えば、以下のようにすればIDをキーにして、パスワードを取得できると思います。

js

1let db = null; 2 3class IDB { 4 constructor(options) { 5 this._dbName = options.databaseName || 'mydb'; 6 this._dbVersion = options.databaseVersion || 1; 7 this._storeName = options.storeName || 'mystore'; 8 this._keyPath = options.keyPath; 9 this._db = null; 10 this._store = null; 11 } 12 13 open() { 14 if(this._db) return; 15 return new Promise((resolve, reject) => { 16 if (this._db) { 17 resolve(); 18 } else { 19 const req = indexedDB.open(this._dbName, this._dbVersion); 20 req.onsuccess = evt => { 21 this._db = req.result; 22 resolve(); 23 }; 24 req.onupgradeneeded = evt => { 25 this._db = req.result; 26 this._store = req.result.createObjectStore(this._storeName, { keyPath: this._keyPath, autoIncrement: this._autoIncrement }); 27 req.transaction.oncomplete = evt => { 28 resolve(); 29 } 30 }; 31 req.onerror = evt => { 32 reject(req.error); 33 }; 34 } 35 }); 36 } 37 38 async putOne(data, storeName) { 39 return new Promise(async (resolve, reject) => { 40 storeName = storeName || this._storeName; 41 if (!data) throw new Error('put no data'); 42 await this.open(); 43 const tx = this._db.transaction(this._storeName, 'readwrite'); 44 const store = tx.objectStore(this._storeName); 45 let err = null; 46 tx.oncomplete = evt => { 47 if (err) { 48 reject(err); 49 } else { 50 resolve(data); 51 } 52 }; 53 tx.onerror = evt => { 54 reject(tx.error); 55 }; 56 const req = store.put(data); 57 req.onerror = evt => { 58 err = req.error; 59 err.data = data; 60 } 61 req.success = evt => { 62 data[this._keyPath] = req.result; 63 } 64 }); 65 } 66 67 async getOne(key) { 68 return new Promise(async (resolve, reject) => { 69 await this.open(); 70 const tx = this._db.transaction(this._storeName); 71 const store = tx.objectStore(this._storeName); 72 let res = null; 73 let err = null; 74 tx.oncomplete = evt => { 75 if (err) { 76 reject(err); 77 } else { 78 resolve(res); 79 } 80 }; 81 tx.onerror = evt => { 82 reject(tx.error); 83 }; 84 const req = store.get(key); 85 req.onsuccess = evt => { 86 res = req.result; 87 }; 88 req.onerror = evt => { 89 err = req.error; 90 }; 91 }); 92 } 93} 94 95 96const idb = new IDB({ 97 databaseName: 'mydb', 98 storeName: 'mystore', 99 keyPath: 'MYID', 100}); 101 102async function idbPut(data) { 103 try { 104 await idb.open(); 105 idb.putOne(data); 106 } catch(err) { 107 console.log(err); 108 } 109} 110 111async function idbGet(id) { 112 try { 113 const res = await idb.getOne(id); 114 return res.pass; 115 } catch(err) { 116 console.log(err); 117 } 118} 119// indexedDBにユーザー登録 120idbPut({MYID:'MYID', pass:'PASS'}); 121 122// indexedDBからユーザー(のパス)を取得 123idbGet('MYID').then(pass => console.log(pass));

投稿2018/01/01 12:18

編集2018/01/01 13:36
turbgraphics200

総合スコア4267

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tajix_japan

2018/01/01 12:56

ありがとうございます。 早速 mydb, mystore, MYID, PASSW2 など自分の環境に合わせて試してみました。 <script> let db = null; class IDB { constructor(options) { this._dbName = options.databaseName || 'mydb'; this._dbVersion = options.databaseVersion || 1; this._storeName = options.storeName || 'mystore'; this._keyPath = options.keyPath; this._db = null; this._store = null; } open() { if(this._db) return; return new Promise((resolve, reject) => { if (this._db) { resolve(); } else { const req = indexedDB.open(this._dbName, this._dbVersion); req.onsuccess = evt => { this._db = req.result; resolve(); }; req.onupgradeneeded = evt => { this._db = req.result; this._store = req.result.createObjectStore(this._storeName, { keyPath: this._keyPath, autoIncrement: this._autoIncrement }); req.transaction.oncomplete = evt => { resolve(); } }; req.onerror = evt => { reject(req.error); }; } }); } async putOne(data, storeName) { return new Promise((resolve, reject) => { storeName = storeName || this._storeName; if (!data) throw new Error('put no data'); await this.open(); const tx = this._db.transaction(storeName, 'readwrite'); const store = tx.objectStore(storeName); let err = null; const tx = store.transaction; tx.oncomplete = evt => { if (err) { reject(err); } else { resolve(data); } }; tx.onerror = evt => { reject(tx.error); }; const req = store.put(data); req.onerror = evt => { err = req.error; err.data = data; } req.success = evt => { data[this._keyPath] = req.result; } }); } async getOne(key) { return new Promise((resolve, reject) => { await this.open(); const tx = req.transaction; let res = null; let err = null; tx.oncomplete = evt => { if (err) { reject(err); } else { resolve(res); } }; tx.onerror = evt => { reject(tx.error); }; req.onsuccess = evt => { res = req.result; }; req.onerror = evt => { err = req.error; }; }); } } const idb = new IDB({ databaseName: 'mydb', storeName: 'mystore', keyPath: 'MYID', }); async function idbPut(data) { try { await idb.open(); idb.putOne(data); } catch(err) { console.log(err); } } async function idbGet(id) { try { const pass = idb.getOne(id); return pass; } catch(err) { console.log(err); } } // indexedDBにユーザー登録 idbPut({id:'MYID', pass:'PASS'}); // indexedDBからユーザー(のパス)を取得 const pass = await idbGet(id); </script> としてみたのですが、 Uncaught SyntaxError: await is only valid in async function というエラーが出てブラウザ上では何も表示されませんでした。 awaitは非同期関数でのみ有効とのことで、うまく表示されません。
turbgraphics200

2018/01/01 13:37

解凍のコードを修正したので、コピペしなおしてください
tajix_japan

2018/01/01 21:25

お手数をお掛けし申し訳ございません。 下記のエラーが出てしまい、やはり取得できませんでした。 申し訳ございません。 Uncaught (in promise) DOMException: Failed to execute 'put' on 'IDBObjectStore': Evaluating the object store's key path did not yield a value. at Promise (URL) at <anonymous>
turbgraphics200

2018/01/01 22:50

開発ツールで、Applicationタブを開き、キーパスが何になっているか確認してください。
tajix_japan

2018/01/01 23:33

ありがとうございます。 mystore → myvalueIndex と辿ると Key(key path: "myvalue") Primary key (key path: "mykey") となっております。
turbgraphics200

2018/01/02 01:22

となると、 store.put({myvalue:'MYID', pass:'PASS'})といった値を登録しなければなりません。 createObjectStore()時にkyePathを設定しますが、例えば db.createObjectStore('hoge', {keyPath:'fuga'}); として、ストアを作成した場合、 store.put({fuga:'piyo', value: 'val'}); というように、DBに登録するオブジェクトのキーにkeyPathで指定した'fuga'を含めなければなりません。 このfugaキーがhogeストアのキーとなり、hogeストアから値を取得するとき、store.get('piyo')とすれば{fuga:'piyo', value: 'val'}が取得できます。
tajix_japan

2018/01/02 03:25

すみません。言葉足らずでした。 下記のとおり登録されているようです。 Application Start from key Key(key path: "mykey") "ID" Value ▼Object mykey; "ID" myvalue; "YAMADA" "PASS" Value ▼Object mykey; "PASS" myvalue; "123" となっております。
turbgraphics200

2018/01/02 03:50

なぜ、わざわざ"ID"と"PASS"の2つに分けて登録しているのかがわからないのですが。 2つに分けて登録すると、別途、2つの値を紐づけるプロパティが必要になってきますよね? 2つに分けずに、 store.put({mykey:"YAMADA", myvalue:"123"}) と登録すれば store.get("YAMADA")で、{mykey:"YAMADA", myvalue:"123"}が取得できるのですが。
tajix_japan

2018/01/02 05:01

ありがとうございます。 そもそもの設計が間違っているということですね。 indexedDBは初めてなので、拾ってきたソースを改造しながらやったため 根本が間違っているようです。 頂きましたソースをベースに再度勉強しなおしてみます。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問