i have a few object stores, and split things up between them. and during initial install of chrome extension, i am adding data to the various object stores, and i am wanting to make sure the data aligns up correctly. so when things go out of sync during install. the "keypath / id" will match things up correctly. nothing big there.
issue es in after the initial install. and adding another record. and the "id" / keyPath / key for initial records are showing id:1, id:2, id:3, etc...
but for a record after initial install. i no longer know what the key will be until it is added to the objectstore. is there a code snip i am missing so i can create an object and add to objecstore, to also up the id, or did i mess up originally creating id: 1 and should of used something like keyPath: 1 or key: 1 or Primarykey: 1?
i can take long way around it, and use some promises, and
objectstore.add(object)
.then(objecstore.get(event.key)
.then(objestore.put(key, {"id":key})
i do note remember correct promise code to above. but objectstore.add, then getting key once added, then .put({"id": key}) to update "id" is done, is the jist of it. i am trying to prevent ever needing to do this in the first place.
kinda like in SQL like database, and having 2 primarykeys that are numbers, autoinncrement, and are exactly same in every way for the same table. but in my case, keys update, and "id" is taking up space. and not sure how to remove 'id' from initial get go. Or once done, how to keep keys and 'id' synced without a bunch of extra blah promises.
ments in below code, trying to figure it out. and no success as of yet figuring it out myself
const ms_master = [{
//========================
//did i mess up here in creating id: and should of used like keypath:1?
//========================
"id": 1,
"baseurl": "www.example1",
"prefix": "ex1",
"name": "tryout1",
}, {
"id": 2,
"baseurl": "www.something",
"prefix": "so",
"name": "some some",
}, {
"id": 3,
"baseurl": "woops",
"prefix": "woo",
"name": "arghs",
}]
var db;
var request = window.indexedDB.open("mystyle", 1);
request.onerror = function(event) {
console.log("error: ")
};
request.onsuccess = function(event) {
db = event.target.result;
console.log("success: " + db);
};
request.onupgradeneeded = function(event) {
var db = event.target.result;
if (!db.objectStoreNames.contains("ms_master")) {
//========================
//did i mess up here in creating the store?
//========================
var objectStore = db.createObjectStore("ms_master", {
keypath: "id",
autoIncrement: true,
unique: true
});
objectStore.createIndex("baseurl", "baseurl", {
unique: false
});
objectStore.createIndex("prefix", "prefix", {
unique: false
});
objectStore.createIndex("name", "name", {
unique: false
});
//========================
//seems to make no difference
//========================
//objectStore.createIndex("id","id", { unique: true });
for (var i in ms_master) {
objectStore.add(ms_master[i]);
}
//========================
//once added, should i do a objecstore.get and grab data, then do a objectstore.put that does not have 'id" in it?
//========================
}
$(document).ready(function() {
document.getElementById('ms_table_add').addEventListener("click", ms_table_add);
}
function ms_table_add() {
var db;
var request = indexedDB.open('mystyle', 1);
request.onsuccess = function(e) {
db = e.target.result;
var transaction = db.transaction('ms_master', "readwrite");
var objectStore = transaction.objectStore('ms_master');
var myobj = [
"id",
"name",
"prefix",
"baseurl"
];
var myarray = {};
for (var h = 0; h < myobj.length; h++) {
if (h == 0) {
//========================
//am i not getting the correct code to get id and keypath to sync up?
//========================
//{name: 'ms_master', keyPath: 'id'}
//myarray[myobj[h]] = 'id';
} else {
var temp = document.getElementById('ms_table_add_' + myobj[h]).value;
if (typeof temp !== "undefined" && temp !== null && temp !== "") {
myarray[myobj[h]] = temp;
}
}
}
objectStore.add(myarray);
//==============================
//trying to avoid extra promises to add, then get key, then update id here.
//==============================
document.getElementById("ms_listings_master_add").innerHTML = "";
}
}
function site_adding() {
//function that builds up a html form / textareas / inputs and .innerhtml into
//<div id="ms_listings_master_add"></div>
}
<script src=".11.1/jquery.min.js"></script>
<button id="site_adding">add a site</button>
</br>
<div id="ms_listings_master_add"></div>
i have a few object stores, and split things up between them. and during initial install of chrome extension, i am adding data to the various object stores, and i am wanting to make sure the data aligns up correctly. so when things go out of sync during install. the "keypath / id" will match things up correctly. nothing big there.
issue es in after the initial install. and adding another record. and the "id" / keyPath / key for initial records are showing id:1, id:2, id:3, etc...
but for a record after initial install. i no longer know what the key will be until it is added to the objectstore. is there a code snip i am missing so i can create an object and add to objecstore, to also up the id, or did i mess up originally creating id: 1 and should of used something like keyPath: 1 or key: 1 or Primarykey: 1?
i can take long way around it, and use some promises, and
objectstore.add(object)
.then(objecstore.get(event.key)
.then(objestore.put(key, {"id":key})
i do note remember correct promise code to above. but objectstore.add, then getting key once added, then .put({"id": key}) to update "id" is done, is the jist of it. i am trying to prevent ever needing to do this in the first place.
kinda like in SQL like database, and having 2 primarykeys that are numbers, autoinncrement, and are exactly same in every way for the same table. but in my case, keys update, and "id" is taking up space. and not sure how to remove 'id' from initial get go. Or once done, how to keep keys and 'id' synced without a bunch of extra blah promises.
ments in below code, trying to figure it out. and no success as of yet figuring it out myself
const ms_master = [{
//========================
//did i mess up here in creating id: and should of used like keypath:1?
//========================
"id": 1,
"baseurl": "www.example1",
"prefix": "ex1",
"name": "tryout1",
}, {
"id": 2,
"baseurl": "www.something.",
"prefix": "so",
"name": "some some",
}, {
"id": 3,
"baseurl": "woops",
"prefix": "woo",
"name": "arghs",
}]
var db;
var request = window.indexedDB.open("mystyle", 1);
request.onerror = function(event) {
console.log("error: ")
};
request.onsuccess = function(event) {
db = event.target.result;
console.log("success: " + db);
};
request.onupgradeneeded = function(event) {
var db = event.target.result;
if (!db.objectStoreNames.contains("ms_master")) {
//========================
//did i mess up here in creating the store?
//========================
var objectStore = db.createObjectStore("ms_master", {
keypath: "id",
autoIncrement: true,
unique: true
});
objectStore.createIndex("baseurl", "baseurl", {
unique: false
});
objectStore.createIndex("prefix", "prefix", {
unique: false
});
objectStore.createIndex("name", "name", {
unique: false
});
//========================
//seems to make no difference
//========================
//objectStore.createIndex("id","id", { unique: true });
for (var i in ms_master) {
objectStore.add(ms_master[i]);
}
//========================
//once added, should i do a objecstore.get and grab data, then do a objectstore.put that does not have 'id" in it?
//========================
}
$(document).ready(function() {
document.getElementById('ms_table_add').addEventListener("click", ms_table_add);
}
function ms_table_add() {
var db;
var request = indexedDB.open('mystyle', 1);
request.onsuccess = function(e) {
db = e.target.result;
var transaction = db.transaction('ms_master', "readwrite");
var objectStore = transaction.objectStore('ms_master');
var myobj = [
"id",
"name",
"prefix",
"baseurl"
];
var myarray = {};
for (var h = 0; h < myobj.length; h++) {
if (h == 0) {
//========================
//am i not getting the correct code to get id and keypath to sync up?
//========================
//{name: 'ms_master', keyPath: 'id'}
//myarray[myobj[h]] = 'id';
} else {
var temp = document.getElementById('ms_table_add_' + myobj[h]).value;
if (typeof temp !== "undefined" && temp !== null && temp !== "") {
myarray[myobj[h]] = temp;
}
}
}
objectStore.add(myarray);
//==============================
//trying to avoid extra promises to add, then get key, then update id here.
//==============================
document.getElementById("ms_listings_master_add").innerHTML = "";
}
}
function site_adding() {
//function that builds up a html form / textareas / inputs and .innerhtml into
//<div id="ms_listings_master_add"></div>
}
<script src="https://ajax.googleapis./ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button id="site_adding">add a site</button>
</br>
<div id="ms_listings_master_add"></div>
Share
Improve this question
edited Oct 11, 2016 at 9:20
Ryan Sanders
asked Oct 11, 2016 at 8:47
Ryan SandersRyan Sanders
1511 silver badge8 bronze badges
1
- Please post details as concise as possible. – Rax Weber Commented Oct 11, 2016 at 8:49
2 Answers
Reset to default 9You're using two features together - in-line keys and key generators. I'll explain them both separately then how they pose.
In-Line and Out-of-Line Keys
In-line keys have the key value appear in the record itself - a store with a keyPath uses in-line keys. By contrast, out-of-line keys have the key value separate.
var storeWithOutOfLineKeys = db.createObjectStore('s1');
storeWithOutOfLineKeys.put({name: 'alice'}, 1);
var storeWithInLineKeys = db.createObjectStore('s2', {keyPath: 'id'});
storeWithInLineKeys.put({name: 'bob', id: 1});
Calls to put()
and add()
will fail if you don't supply an explicit key for a store with out-of-line keys. Calls to put()
and add()
will fail if you do supply an explicit key to a store with in-line keys, and will fail if the record does not contain the in-line key value (e.g. missing the id
property in the above example)
Key Generators
When you specify autoIncrement: true
you're using what the spec calls a key generator. For each record added, if not specified otherwise then the first will get 1
, the second 2
, etc. You can find out what key was used by looking at the result of the put()
or add()
request, e.g.
var request = store.put({name: 'alice'});
request.onsuccess = function() {
console.log('put got generated key: ' + request.result;
};
Both In-Line Keys and Key Generators
When a key generator is used, the behavior of add()
and put()
change:
Key generator and out-of-line keys: it is not necessary to pass an explicit key when calling add()
or put()
; if omitted, the generated key is used:
var storeWithOutOfLineKeys = db.createObjectStore('s1', {autoIncrement: true});
storeWithOutOfLineKeys.put({name: 'alice'});
If an explicit key is passed it will be used, either overwriting a previous record or adding a new one. (If the key passed happens to be a number higher than the generator value, the generator will be set to that number.)
Key generator and in-line keys: it is not necessary to specify the key in the record when calling add()
or put()
; if omitted, the generated key is injected into the value.
var storeWithInLineKeys = db.createObjectStore('s2', {keyPath: 'id', autoIncrement: true});
storeWithInLineKeys.put({name: 'bob'}).onsuccess = function(e) {
var id = e.target.result;
storeWithInLineKeys.get(id).onsuccess = function(e) {
console.log(JSON.stringify(e.target.result));
// {"name": "bob", "id": 1}
});
});
Similarly though, if the record does contain a key value it will be used instead. (And if it's a number higher than the key generator state, the key generator will be adjusted.)
I believe this last case matches what your code is doing - both in-line keys and a key generator. You can use the result of add()
and put()
requests to determine the key that was added, and update records by specifying the key explicitly in the record:
storeWithInLineKeys.put({name: 'eve', id: 1}); // overwrites old #1
this is what i was looking for ((from How do I specify key when adding records to objectStore w/ in IndexedDB?)) bined with your post Joshua Bell. it clicked :) thank you!
objectStore.add({name: "myData"}, 47);
i need to restructure below, so i can remove 'id' itself pletely, and still have key notation # 47 in above text.
const ms_master = [{
"id": 1,
"baseurl": "www.example1",
"prefix": "ex1",
"name": "tryout1",
}, {
"id": 2,
"baseurl": "www.something.",
"prefix": "so",
"name": "some some",
}, {
"id": 3,
"baseurl": "woops",
"prefix": "woo",
"name": "arghs",
}]
1st example of yours
var storeWithOutOfLineKeys = db.createObjectStore('s1');
storeWithOutOfLineKeys.put({name: 'alice'}, 1);
4th example of yours
var storeWithOutOfLineKeys = db.createObjectStore('s1', {autoIncrement: true});
storeWithOutOfLineKeys.put({name: 'alice'});
new doing...
var storeWithOutOfLineKeys = db.createObjectStore('s1', {autoIncrement: true});
//for initial putting data into indexeddb (during install of chrome extension)
storeWithOutOfLineKeys.add({name: 'alice'}, 1);
//for adding data at a later time
storeWithOutOfLineKeys.add({name: 'alice'});
//for updating something...
storeWithOutOfLineKeys.put({name: 'alice'}, 1);