IndexedDB is a way to store data in the browser.
It lets us store larger amounts of data than local storage in an asynchronous way.
Dexie makes working with IndexedDB easier.
In this article, we’ll take a look at how to start working with IndexedDB with Dexie.
Ordering
We can order queries with the between
method.
For example, we can write:
(async () => {
const db = new Dexie("friend_database");
try {
await db.version(1).stores({
friends: '++id,[firstName+lastName],age'
});
await db.friends.put({
firstName: "jane",
lastName: 'smith',
age: 39
})
await db.friends.put({
firstName: "jane",
lastName: 'wong',
age: 28
})
const someFriends = await db.friends
.where('[firstName+lastName]')
.between(["jane", ""], ["jane", "uffff"])
.toArray()
console.log(someFriends)
} catch (error) {
console.log(error);
}
})()
We call between
with ''
and 'uffff'
in the 2nd entry to order the results by lastName
.
Also, we can search for items with other methods that act as operators.
For instance, we can write:
(async () => {
const db = new Dexie("friend_database");
try {
await db.version(1).stores({
friends: '++id,firstName,lastName,age,shoeSize,interests'
});
await db.friends.put({
firstName: "jane",
lastName: 'smith',
age: 39,
shoeSize: 7,
interests: ['sports', 'pets'],
tags: []
})
await db.friends.put({
firstName: "jane",
lastName: 'wong',
age: 28,
shoeSize: 9,
interests: [],
tags: []
})
const someFriends = await db.friends
.where('age').above(25)
.or('shoeSize').below(8)
.or('interests').anyOf('sports', 'pets', 'cars')
.modify(friend => friend.tags.push("marketing-target"));
} catch (error) {
console.log(error);
}
})()
We add the items with the age
, shoeSize
, and interests
fields as index fields.
Then we search for the age
with the where
and above
methods.
Then we use the or
method to search for the shoeSize
below a given size with the below
method.
And we use the anyOf
method to search if the given values are in the interests
array.
Then we call modify
to add the tags
value to the array.
Retrieve First n Items
We can search for the first n
items with the limit
method.
For instance, we can write:
(async () => {
const db = new Dexie("friend_database");
try {
await db.version(1).stores({
friends: '++id,firstName,lastName,age'
});
await db.friends.put({
firstName: "jane",
lastName: 'smith',
age: 39,
})
await db.friends.put({
firstName: "jane",
lastName: 'wong',
age: 28,
})
const someFriends = await db.friends
.orderBy("age")
.reverse()
.limit(5)
.toArray();
console.log(someFriends)
} catch (error) {
console.log(error);
}
})()
We call orderBy
to get the entries ordered by age
.
We call reverse
to sort them by reverse order.
limit
limits the number of items returned to the given number.
Joining
We can join multiple tables together.
For example, we can write:
(async () => {
const db = new Dexie('music');
try {
db.version(1).stores({
albums: '++id,name,*tracks',
bands: '++id,name,*albumIds'
});
const a1 = await db.albums.put({
name: 'Arrival',
year: 1974
})
const a2 = await db.albums.put({
name: 'Waterloo',
year: 1974
})
await db.bands.put({
name: "Abba",
albumIds: [a1, a2]
})
const bands = await db.bands
.where('name')
.startsWith('A')
.toArray();
const someBands = await Promise.all(bands.map(async band => {
band.albums = await db.albums.where('id').anyOf(band.albumIds).toArray()
return band
}));
console.log(someBands)
} catch (error) {
console.log(error);
}
})()
We created the albums
and bands
tables.
Then we populate them with our own data.
a1
and a2
are the IDs for the album
entries.
We use then to populate the albumId
fields of the band
.
Then we query the band
with:
const bands = await db.bands
.where('name')
.startsWith('A')
.toArray();
Then we add the albums
to the band
with:
const someBands = await Promise.all(bands.map(async band => {
band.albums = await db.albums.where('id').anyOf(band.albumIds).toArray()
return band
}));
We just attach the child items to a property of the parent.
Conclusion
We can order items and join multiple tables with Dexie.