I have the following code:
(function () {
var gameDataLocalStorageName = "myTest3";
var defaultUserSettings = {
volumes: {
musicVolume: 0.3,
sfxVolume: 0.5,
voicesVolume: 1
}
};
var savedGames = [
{
screenshot: "data uri here",
day: "1",
month: "1",
year: "1",
time: "1",
gameData: {
fonts: [{
id: 123,
name: "Arial"
}],
globalSpeeches: {
anotherVal: "something"
}
}
}
];
console.log(gameDataLocalStorageName);
console.log(defaultUserSettings);
console.log(savedGames);
/* Create db START */
var db = new Dexie(gameDataLocalStorageName);
db.version(1).stores({
usersData: ""
});
db.usersData.put(defaultUserSettings, 'userSettings');
db.usersData.put(savedGames, 'savedGames');
}());
/* Create db END */
/* Recall db START */
setTimeout(function(){
var db2 = new Dexie("myTest3");
db2.version(1).stores({
usersData: "userSettings,savedGames"
});
db2.usersData.toArray().then(function (results) {
console.log("User settings is: ", results[1]);
console.log("Saved games is: ", results[0]);
});
}, 3000);
Which runs great. However how can I obtain the data again without having to render out as an array toArray()
. Currently to obtain them I have to hardcode results[0]
and results[1]
which is also not in the same order as I entered them into the db.
Ideally I want to do something like:
db2.get('usersData.userSettings');
db2.get('usersData.savedGames');
The sample show you are changing primary key which is not supported:
The first declaration specifies a table "usersData" with outbound primary keys:
db.version(1).stores({
usersData: ""
});
Then in the setTimout callback, you redeclare it with:
db2.version(1).stores({
usersData: "userSettings,savedGames"
});
...which means you want an inbound primary key from the property "userSettings" and and index on property "savedGames".
There are three errors here:
It seems what you really intend is so use Dexie as a key/value store, which is perfectly ok but much simpler to do than the sample shows.
If you put() (or add()) a value using a certain key, you retrieve the same using get().
If so, try the following:
db.version(1).stores({
usersData: "",
});
And don't forget to catch promises or await and do try/catch.
(async ()=>{
await db.usersData.put(defaultUserSettings, 'userSettings')
await db.usersData.put(savedGames, 'savedGames');
// Get using key:
const userSettings = await db.usersData.get('userSettings');
console.log("User settings is: ", userSettings);
const savedGames = await db.usersData.get('savedGames');
console.log("User settings is: ", savedGames);
})().catch(console.error);
However, putting entire arrays as values in a key/value store is not very optimal.
Maybe only have two tables "userSettings" and "savedGames" where each saved game would be its own row? Will you support multiple users or just one single user? If multiple, you could add an index "userId" to your tables.
If so, try the following:
db.version(2).stores({
userSettings: "userId" // userId is primary key
savedGames: "++gameId, userId" // incremented id and userId is foreign key
});
(async ()=>{
await db.userSettings.put({...defaultUserSettings, userId: "fooUser"});
await db.savedGames.bulkPut(savedGames.map(game =>
({...game, userId: "fooUser"}));
// Get user settings:
const userSettings = await db.usersData.get('fooUser');
console.log("User settings is: ", userSettings);
const savedGames = await db.usersData.where({userId: "fooUser"}).toArray();
console.log("Saved games for fooUser are: ", savedGames);
})().catch(console.error);