Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Не могу прочитать данные из IndexedDB (https://javascript.ru/forum/misc/79744-ne-mogu-prochitat-dannye-iz-indexeddb.html)

amon--ra 18.03.2020 00:16

Не могу прочитать данные из IndexedDB
 
Здравствуйте.
Есть такой код:

function getRec(Rec, f){
connectDB(function(db){
var request = db.transaction([storeName], "readonly").objectStore(storeName).get(id=0);
request.onerror = logerr;
request.onsuccess = function(){
Rec = request.result;
console.log(Rec);
f(request.result ? request.result : -1);
}
});
}

Вывод в консоль самого Rec я вижу в хроме.
Но, например, Rec.width консоль выдает undefined.

Записать объект Rec {width : 1000, .....} мне удалось, а вот прочитать записанное из другого файла js не могу.

Я только пытаюсь освоить js.
Помогите, может кто-то рабочий код подкинет?
Дальше я сам попробую разобраться.
Заранее благодарен.

voraa 18.03.2020 18:18

Что значит из "другого файла js"?
С другой html страницы? Вы их запускаете с сервера из одного домена?

amon--ra 19.03.2020 21:08

Я запускаю на локальном компьютере без серверов и прочего.
Планирую сделать расширение, способное работать вообще без сети.
Что-то похожее на speed dial 2.

voraa 19.03.2020 21:36

IndexedDB работает по политике одного источника. Т.е базу данных могут использовать страницы только с того же домена, что и страница создавшая базу. При загрузке страниц с локального компьютера из файловой системы понятия домена нет. Поэтому и не работает.

amon--ra 19.03.2020 21:45

Вы не поняли.
У меня все работает. Я, например, могу записать в IDB запись, т. е. объект вида let D = {"length" : 100, "Q" : 200 ...}. И прочитать D могу при помощи транзакции - в консоли он виден. Но вот к его свойствам доступа нет, например, D.width и т.д. Я подозреваю, что вообще детскую ошибку делаю, возможно, на уровне лексики языка. Поэтому и прошу посмотреть рабочий код, который читает из БД, записывает в нее и редактирует выбранную запись. Я только начинаю изучать JS, поэтому возможны элементарные ляпы.
А Вам спасибо большое - Вы хотя бы откликнулись на зов чайника.

voraa 19.03.2020 23:29

Цитата:

Сообщение от amon--ra (Сообщение 521534)
Вы не поняли.
У меня все работает. Я, например, могу записать в IDB запись, т. е. объект вида let D = {"length" : 100, "Q" : 200 ...}. И прочитать D могу при помощи транзакции - в консоли он виден. Но вот к его свойствам доступа нет, например, D.width и т.д. Я подозреваю, что вообще детскую ошибку делаю, возможно, на уровне лексики языка. Поэтому и прошу посмотреть рабочий код, который читает из БД, записывает в нее и редактирует выбранную запись.

Ну так покажите код, что было ясно, что записываете, что читаете.
Что именно видно в консоле?

console.log(Rec);
Что выводится?

SuperZen 20.03.2020 13:33

взял тут https://developers.google.com/web/il...with-indexeddb
dbPromise.then(function(db) {
  var tx = db.transaction('store', 'readonly');
  var store = tx.objectStore('store');
  return store.get('sandwich');
}).then(function(val) {
  console.dir(val);
});


это Promise
return store.get('sandwich')


потом идет then и там уже значение...

voraa 20.03.2020 17:14

Цитата:

Сообщение от voraa (Сообщение 521533)
IndexedDB работает по политике одного источника. Т.е базу данных могут использовать страницы только с того же домена, что и страница создавшая базу. При загрузке страниц с локального компьютера из файловой системы понятия домена нет. Поэтому и не работает.

Я ошибался. Файрфокс действительно не работает при загрузке с локального файла, но Хромовые браузеры работают. Причем им доступна база данных, независимо от того, из какого каталога запускается страница.

amon--ra 21.03.2020 01:19

Доброго времени суток.
Вот весь код.


var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB,
IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction,
baseName = "Base_0",
storeName = "Options";
storeName1 = "List";

let f = function() {};
let Rec = {};


function logerr(err){
console.log(err);
}

function connectDB(f){
var request = indexedDB.open(baseName, 1);
request.onerror = logerr;
request.onsuccess = function(){
f(request.result);
}
request.onupgradeneeded = function(e){
e.currentTarget.result.createObjectStore(storeName , { keyPath: "id" });
e.currentTarget.result.createObjectStore(storeName 1, { keyPath: "path" });
connectDB(f);
}
}

function getRec(Rec, f){
connectDB(function(db){
var request = db.transaction([storeName], "readonly").objectStore(storeName).get(id=0);
request.onerror = logerr;
request.onsuccess = function(){
Rec = request.result;
console.log(Rec);
f(request.result ? request.result : -1);
}
});
}

function getStorage(f){
connectDB(function(db){
var rows = [],
store = db.transaction([storeName], "readonly").objectStore(storeName);

if(store.mozGetAll)
store.mozGetAll().onsuccess = function(e){
f(e.target.result);
};
else
store.openCursor().onsuccess = function(e) {
var cursor = e.target.result;
if(cursor){
rows.push(cursor.value);
cursor.continue();
}
else {
f(rows);
}
};
});
}

function setRec(Rec){
connectDB(function(db){
var request = db.transaction([storeName], "readwrite").objectStore(storeName).put({Value : Rec, "id": 0});
request.onerror = logerr;
request.onsuccess = function(){
return request.result;
}
});
}

function delRec(Rec){
connectDB(function(db){
var request = db.transaction([storeName], "readwrite").objectStore(storeName).delete(Rec );
request.onerror = logerr;
request.onsuccess = function(){
console.log("Record delete from DB:", Rec);
}
});
}
document.addEventListener('DOMContentLoaded', function init() {

connectDB(f);

//Rec.width = 500;
//setRec(Rec);
//console.log(Rec);

getRec(Rec, f);

console.log(Rec);

}, false);

Это будущее расширение хром.
Оно работает в браузере на локальной машине.
Там нет никаких серверов.
У Вас может есть рабочий код работы с IndexedDB?
Такой что бы читал и писал.
Последнее не обязательно - запись целого объекта из этого кода работает.
Мне всего-то нужно прочитать поля объекта, а не объект целиком.
Целиком он читается.

рони 21.03.2020 01:32

amon--ra,
Пожалуйста, отформатируйте свой код!

Для этого его можно заключить в специальные теги: js/css/html и т.п., например:
[html run]
... минимальный код страницы с вашей проблемой
[/html]

О том, как вставить в сообщение исполняемый javascript и html-код, а также о дополнительных возможностях форматирования - читайте http://javascript.ru/formatting.

voraa 21.03.2020 14:45

amon--ra,
Вот работающий пример

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-type" content="text/html; charset=utf-8" lang="ru">
  <meta name="viewport" content="width=device-width, initial-scale=1.0" >
  <title>TEST INDEXEDDB</title>
<style>
input {width:100px;}
</style>
<script>
var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB,
IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction,
baseName = "Base_0",
storeName = "Options";


function connectDB(bname){
	return new Promise ((res, rej) => {
		let request = indexedDB.open(bname, 1);
		request.onerror = () => rej (request.error) ;
		request.onsuccess = () => res (request.result);
		request.onupgradeneeded = function(e){
			e.currentTarget.result.createObjectStore(storeName , { keyPath: "id" });
		}
	})
}

function getRec(db,  sname, key){
	return new Promise ((res, rej) => {
		let request = db.transaction([sname], "readonly").objectStore(sname).get(key);
		request.onerror = () => rej (request.error) ;
		request.onsuccess = () => res (request.result);
	});
}

function addRec(db, sname, value){
	return new Promise ((res, rej) => {
		let request = db.transaction([sname], "readwrite").objectStore(sname).add(value);
		request.onerror = () => rej (request.error) ;
		request.onsuccess = () => res (request.result);
	});
}
function countRec(db, sname){
	return new Promise ((res, rej) => {
		let request = db.transaction([sname], "readwrite").objectStore(sname).count();
		request.onerror = () => rej (request.error) ;
		request.onsuccess = () => res (request.result);
	});
}

const dbcount = async ()=> {
	let db = await connectDB(baseName)
	let n = await countRec(db, storeName)
	document.getElementById('dbcount').innerHTML = `Записей в хранилище: ${n}`
}

document.addEventListener('DOMContentLoaded', function init() {
	document.getElementById('putbut').onclick = async () => {
		const key = document.getElementById('putkey').value
		const field1 = document.getElementById('putval1').value
		const field2 = document.getElementById('putval2').value
		const val = {id: key, field1: field1, field2: field2}
		let db = await connectDB(baseName)
		await addRec(db, storeName, val)
		console.log('Записано : ', val)
		document.getElementById('putrestext').innerHTML = `Записано ${key}`
		dbcount()
	}
	
	document.getElementById('getbut').onclick = async () => {
		const key = document.getElementById('getkey').value
		let db = await connectDB(baseName)
		let val = await getRec(db, storeName, key)
		console.log('Прочитано : ', val)
		document.getElementById('getrestext').innerHTML = 
		val? `Прочитано : {id:'${val.id}',field1:'${val.field1}', field2:'${val.field2}'}`
			: `Нет записи с ключом '${key}'`
		
	}
	
	dbcount()
 
});
</script>
</head>

<body>
<section>
	<h3 id='dbcount'> 
	<h3>Запись в базу</h3>
	<label>Ключ : <input type="text" id='putkey'></label>
	<label>Поле 1 : <input type="text" id='putval1'></label>
	<label>Поле 2 : <input type="text" id='putval2'></label>
	<button  id='putbut'>Записать</button>
	<div id=putres>
		<h4>Рузультат записи</h4>
		<span id='putrestext'></span>
	</div>
</section>

<section>
	<h3>Чтение из базы</h3>
	<label>Ключ : <input type="text" id='getkey'></label>
	<button  id='getbut'>Прочитать</button>
	<div id='getres'>
		<h4>Рузультат чтения</h4>
		<span id='getrestext'></span>
	</div>
</section>
</body>
</html>

рони 21.03.2020 14:53

voraa,
строка 76 фигурной скобки не хватает в конце, и может так ...
val? `Прочитано : ${JSON.stringify(val, "", 4)}`

voraa 21.03.2020 15:11

Цитата:

Сообщение от рони (Сообщение 521591)
voraa,
строка 76 фигурной скобки не хватает в конце, и может так ...
val? `Прочитано : ${JSON.stringify(val, "", 4)}`

Спасибо, скобку поставил.
Можно и JSON.stringify, разумеется.
Меня просто раздражают название полей в кавычках, там, где можно без них обойтись.
Но это только мое личное мнение.

laimas 21.03.2020 17:03

https://github.com/coresmart/persistencejs

amon--ra 22.03.2020 15:59

Доброго времени суток.
Вот весь код.

var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB,
IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction,
baseName = "Base_0",
storeName = "Options";
storeName1 = "List";

let f = function() {};
let Rec = {};


function logerr(err){
console.log(err);
}

function connectDB(f){
var request = indexedDB.open(baseName, 1);
request.onerror = logerr;
request.onsuccess = function(){
f(request.result);
}
request.onupgradeneeded = function(e){
e.currentTarget.result.createObjectStore(storeName , { keyPath: "id" });
e.currentTarget.result.createObjectStore(storeName 1, { keyPath: "path" });
connectDB(f);
}
}

function getRec(Rec, f){
connectDB(function(db){
var request = db.transaction([storeName], "readonly").objectStore(storeName).get(id=0);
request.onerror = logerr;
request.onsuccess = function(){
Rec = request.result;
console.log(Rec);
f(request.result ? request.result : -1);
}
});
}

function getStorage(f){
connectDB(function(db){
var rows = [],
store = db.transaction([storeName], "readonly").objectStore(storeName);

if(store.mozGetAll)
store.mozGetAll().onsuccess = function(e){
f(e.target.result);
};
else
store.openCursor().onsuccess = function(e) {
var cursor = e.target.result;
if(cursor){
rows.push(cursor.value);
cursor.continue();
}
else {
f(rows);
}
};
});
}

function setRec(Rec){
connectDB(function(db){
var request = db.transaction([storeName], "readwrite").objectStore(storeName).put({Value : Rec, "id": 0});
request.onerror = logerr;
request.onsuccess = function(){
return request.result;
}
});
}

function delRec(Rec){
connectDB(function(db){
var request = db.transaction([storeName], "readwrite").objectStore(storeName).delete(Rec );
request.onerror = logerr;
request.onsuccess = function(){
console.log("Record delete from DB:", Rec);
}
});
}
document.addEventListener('DOMContentLoaded', function init() {

connectDB(f);

//Rec.width = 500;
//setRec(Rec);
//console.log(Rec);

getRec(Rec, f);

console.log(Rec);

}, false);

voraa 22.03.2020 17:48

let Rec = {};
//........
//.......
*!*function getRec(Rec, f)*/!*{
connectDB(function(db){
var request = db.transaction([storeName], "readonly").objectStore(storeName).get(id=0);
request.onerror = logerr;
request.onsuccess = function(){
*!*Rec = request.result;*/!*
console.log(Rec);
f(request.result ? request.result : -1);
}
});
}
//........
//.......
getRec(Rec, f);

И чему по вашему должен быть Rec после getRec(Rec, f)?
По моему {}.

Причем, console.log(Rec) должен выводить
{Value : {width:500}, id: 0}

(Если при записи были раскоментарены строки
//Rec.width = 500;
//setRec(Rec);
)

Параметр Rec в getRec и Rec = request.result; вообще не нужны
Сделайте так
function getRec( f){
connectDB(function(db){
var request = db.transaction([storeName], "readonly").objectStore(storeName).get(id=0);
request.onerror = logerr;
request.onsuccess = function(){
console.log(request.result);
f(request.result ? request.result : -1);
}
});
}


а вызов

getRec(res => Rec = res);
console.log(Rec);


Часовой пояс GMT +3, время: 04:09.