Dexie returns duplicated object after manually deleting the database and re-populate it.
From: https://stackoverflow.com/questions/78618896/dexie-returns-duplicated-object-after-manually-deleting-the-database-and-re-popu
After deleting Dexie database manually, if you do not refresh the page, it will return duplicated data, even though the chrome inspector shows there are no duplicated rows in the IndexedDB. However, the issue goes away when you refresh the page right away after each database deletion.
Example: https://codesandbox.io/p/sandbox/dexie-issue-forked-djwxz6?file=%2Fsrc%2Findex.tsx
db config:
import Dexie, { EntityTable, Table } from "dexie";
const VERSION = 4.1;
export class MySubClassedDexie extends Dexie {
playlists!: EntityTable<Playlist, "id">;
constructor() {
super("myDatabase");
this.version(VERSION).stores({
playlists: "++id,*competitionIds",
});
}
}
export const db = new MySubClassedDexie();
export const defaultPlaylists: Playlist[] = [
{
id: 1,
competitionIds: [3, 4],
title: "The Trial",
},
{
id: 2,
competitionIds: [1, 2],
title: "Confederations Cup",
},
];
db.on("populate", async () => {
await db.playlists.bulkAdd(defaultPlaylists);
});
export interface Playlist {
competitionIds: CompetitionId[];
title: string;
id: number;
}
Perfect bug report, thanks!
Bug is in the liveQuery cache. To workaround (until we've fixed it), disable the cache (liveQueries still work):
const db = new Dexie('dbName', { cache: 'disabled' });
Bug is in the liveQuery cache. To workaround (until we've fixed it), disable the cache (liveQueries still work):
const db = new Dexie('dbName', { cache: 'disabled' });
Thanks for the update. Is this issue supposed to be fixed in v4.08?
I just updated the code at https://codesandbox.io/p/sandbox/dexie-issue-forked-2qtcl4?file=%2Fsrc%2Fdexie-db.tsx%3A9%2C23
I assume that since the database is empty in the populate event so now I use bulkAdd() instead of bulkPut(), but useLiveQuery() still keeps the default data and keeps adding up on each population.
This is the code I use for populating data again after delete():
export class MySubClassedDexie extends Dexie {
playlists!: EntityTable<Playlist, "id">;
constructor() {
super("myDatabase");
this.version(4.4).stores({
playlists: "id",
});
this.on("populate", async () => {
await db.playlists.bulkAdd([...defaultPlaylists]);
});
}
}
Thanks for finding. This issue was due to another cause, explained in #2040.
I just want to post it here for people who may encounter this issue:
Example code: https://codesandbox.io/p/sandbox/dexie-issue-forked-djwxz6
I'm not able to re-create this elusive issue with code sandbox, but on my production site, with a collection using a compound index as the primary index:
export class MySubClassedDexie extends Dexie {
skills!: Table<Skill>;
constructor() {
super("myDatabase");
this.version(13)
.stores({
skills: "[year+teamId],teamId",
})
}
}
export interface Skill {
year: number;
teamId: number;
rating: number;
text: string;
}
After you run bulkUpdate(), if you (inappropriately?) use :
const strength2 = useLiveQuery(() => {
return db.strengths.where("[year+teamId]").equals([year, teamId]).first();
}, [year, teamId]);
It would show the outdated data.
You have to use get() so that the data is not dated:
const strength = useLiveQuery(() => {
return db.strengths.get([year, teamId]);
}, [year, teamId]);
Again, I can't recreate it in code sandbox but using where().equal().first() may serve outdated data in my specific case. Disabling cache would solve this issue (not ideal?).
Again, I can't recreate it in code sandbox but using
where().equal().first()may serve outdated data in my specific case. Disabling cache would solve this issue (not ideal?).
Curious on whether you experience a single render on outdated data that immediately is being replaced with updated data, or whether the outdated data stays? Since cache: 'disabled' solves it, this is definitely something cache related. It's a pity you cannot reproduce it outside your application - it would have been great to get a repro of this.
Again, I can't recreate it in code sandbox but using
where().equal().first()may serve outdated data in my specific case. Disabling cache would solve this issue (not ideal?).Curious on whether you experience a single render on outdated data that immediately is being replaced with updated data, or whether the outdated data stays? Since cache: 'disabled' solves it, this is definitely something cache related. It's a pity you cannot reproduce it outside your application - it would have been great to get a repro of this.
The outdated data stays. Either reload the page, disable caching or use get() to fix it. The stored data in IndexedDB has no problems at all. It's just the useLiveQuery(()=> db.where().equals().first()). I'll keep you posted when I can re-create it in code sandbox.