N
Nuxt8mo ago
Wild

How to share an indexedDb

Hello friends, pretty new to nuxt and js/ts, so maybe a trivial question there, forgive me. How do I instantiate an indexedb and access it through all of my nuxt app ? Many thanks
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.hooks.hookOnce('app:suspense:resolve', () => {
isHydrated.value = true

const db_open_request = window.indexedDB.open("app");
db_open_request.onerror = (event) => {
let indexedDb = false
};
db_open_request.onupgradeneeded = (event) => {
const db = event.target!.result
const objectStore = db.createObjectStore("data");
}
db_open_request.onsuccess = (event) => {
let ddb = event.target!.result // how do I share this
let indexedDb = true // and maybe this too

ddb.onerror = (event: Event) => {
console.error(`Database error: ${event.target!.errorCode}`);
};
};

})
})
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.hooks.hookOnce('app:suspense:resolve', () => {
isHydrated.value = true

const db_open_request = window.indexedDB.open("app");
db_open_request.onerror = (event) => {
let indexedDb = false
};
db_open_request.onupgradeneeded = (event) => {
const db = event.target!.result
const objectStore = db.createObjectStore("data");
}
db_open_request.onsuccess = (event) => {
let ddb = event.target!.result // how do I share this
let indexedDb = true // and maybe this too

ddb.onerror = (event: Event) => {
console.error(`Database error: ${event.target!.errorCode}`);
};
};

})
})
30 Replies
pyplacca
pyplacca8mo ago
Check out localforage. Makes working with IndexedDB a breeze. Pair it with a composable - or a plugin as you have - to achieve your desired result. here's a modified version using useState
export default defineNuxtPlugin((nuxtApp) => {
const idb = useState<{
ddb: IDBDatabase | undefined,
indexedDB: boolean
}>('idb', () => ({
ddb: undefined,
indexedDB: false,
}))

nuxtApp.hooks.hookOnce('app:suspense:resolve', () => {
// isHydrated.value = true

const db_open_request = window.indexedDB.open('app')
db_open_request.onerror = (event) => {
idb.value.indexedDB = false
}
db_open_request.onupgradeneeded = (event) => {
const db = event.target!.result
const objectStore = db.createObjectStore('data')
}
db_open_request.onsuccess = (event) => {
const ddb = event.target!.result
idb.value.ddb = ddb
idb.value.indexedDB = true

ddb.onerror = (event: Event) => {
console.error(`Database error: ${event.target!.errorCode}`)
}
}
})

return {
provide: {
idb,
},
}
})
export default defineNuxtPlugin((nuxtApp) => {
const idb = useState<{
ddb: IDBDatabase | undefined,
indexedDB: boolean
}>('idb', () => ({
ddb: undefined,
indexedDB: false,
}))

nuxtApp.hooks.hookOnce('app:suspense:resolve', () => {
// isHydrated.value = true

const db_open_request = window.indexedDB.open('app')
db_open_request.onerror = (event) => {
idb.value.indexedDB = false
}
db_open_request.onupgradeneeded = (event) => {
const db = event.target!.result
const objectStore = db.createObjectStore('data')
}
db_open_request.onsuccess = (event) => {
const ddb = event.target!.result
idb.value.ddb = ddb
idb.value.indexedDB = true

ddb.onerror = (event: Event) => {
console.error(`Database error: ${event.target!.errorCode}`)
}
}
})

return {
provide: {
idb,
},
}
})
Wild
WildOP8mo ago
Thanks you very much, I'll try that ! I didn't know of this return provide syntax I couldn't use idb in my stores (not found), so I used a composable and it seems to work fine ! Thanks mate
pyplacca
pyplacca8mo ago
make sure the idb plugin is registered before the store
Wild
WildOP8mo ago
Sorry I don't know how to check that ^^
pyplacca
pyplacca8mo ago
you can rename the plugin to 1.{name}.ts the number prefix dictates the order in which the plugins are registered. if no numbers is specified, the plugins will be registered in alphabetical order. https://nuxt.com/docs/guide/directory-structure/plugins#registration-order
Wild
WildOP8mo ago
I saw that, but the stores are in their own folder
pyplacca
pyplacca8mo ago
can you share a screenshot of your directory structure?
Wild
WildOP8mo ago
sure !
No description
pyplacca
pyplacca8mo ago
how are the stores registered? Pinia?
Wild
WildOP8mo ago
yes
pyplacca
pyplacca8mo ago
wait, are you in ssr mode?
Wild
WildOP8mo ago
probably so
pyplacca
pyplacca8mo ago
or is it a SSG site?
Wild
WildOP8mo ago
I have an hydration stuff to fill the store only on the client
pyplacca
pyplacca8mo ago
hmmm. since Pinia runs on the server side as well I'm thinking the plugin won't work because you're only registering it on the client side. I'm not sure how the hydration stuff you've got affects Pinia's ssr capabilities but I get idb.client.ts makes sense because it's a browser API
Wild
WildOP8mo ago
someone helped me setup an onHydration hook so all the same except most of my stores are all empties after hydration and check the localstorage(now) indexdb is the target well my way of doing idb is faillible, if I load directly a page with a store the idb is empty yeah I cant get it to work, ref is always empty if the starting page has an indexeddb. it feels like the plugin is properly called in both cases, but the indexedbd calls being async make the ref/state update "late" and when store calls it it's empty instead of referring to the db actually if the page could wait on the plugin somehow maybe it could help
pyplacca
pyplacca8mo ago
With this, I suspect the issue might be with the order in which the idb and pinia plugins are registered Plugins are registered before any component renders
pyplacca
pyplacca8mo ago
Assuming you were handling the registration of the stores yourself, you could’ve done something like this https://nuxt.com/docs/guide/directory-structure/plugins#plugins-with-dependencies
Nuxt
plugins/ · Nuxt Directory Structure
Nuxt has a plugins system to use Vue plugins and more at the creation of your Vue application.
Wild
WildOP8mo ago
well simple console.log confirms this
pyplacca
pyplacca8mo ago
Yeah, but it seems fine when you log it in a watcher or view it in your template Have you tried awaiting it?
Wild
WildOP8mo ago
I tried awaiting the idb.value, but since the ref is undefined it doesn't do anything
pyplacca
pyplacca8mo ago
Can you provide a demo link? Maybe I could check it out and provide better assistance if possible
Wild
WildOP8mo ago
any website reco for this ?
Wild
WildOP8mo ago
Wild-Profus
StackBlitz
Nuxt - Starter (forked) - StackBlitz
Create a new Nuxt project, module, layer or start from a theme with our collection of starters.
Wild
WildOP8mo ago
seems pretty representative maybe I should make this a pinia plugin, maybe it'll be loaded right then
pyplacca
pyplacca8mo ago
Oh Pinia has plugins? Didn’t know that. Try that let’s see I’ve personally not had trouble working with IndexedBD in a Pinia store even with SSR enabled
Wild
WildOP8mo ago
Lol this is unfair xD Maybe I thinking about it all wrong is my stackblitz fine or should I redo it with nuxt.new ?
pyplacca
pyplacca8mo ago
I just left home. I’ll check it out when I return
Wild
WildOP8mo ago
I'd love an example as I am not that versed in js/nuxt world but it seems exactly like what I am trying to do, I'm having a hard type with the async and onsuccess events I am trying to initialize the indexeddb only once and then share a ref (not vue ref because I don't think reactivity is usefull here) to avoid all the onsuccess/ onerror boilerplate, is that what you do in your composable ? We used a plugin with @pyplacca to instanciate our db, can this be bypassed with just using a composable ? can you do mycomposable.transaction... in your stores ? or should this be handled in the composable itself ? oh I see, you're using the localforage mentionned. I see the plugin is nuxt2 only, you use localforage directly ? Thanks for the code sample I am very close ! @pyplaca still a order issue thing, I found here https://medium.com/testing-nuxt-applications/introduction-to-nuxt-plugins-and-modules-7f10887ef31b that nuxt load Modules then plugin. So as a pinia plugin, it get loaded before other plugin. However, the time it take to resolve is enough to break the store, which starts hydrating before the plugin finished its' async stuff ! In parts due to me switchin from my homemade onHydrated trigger for the hydrate pinia function. I see that if I was waiting for it, it would work. Any idea of how I could nicely wait for the plugin to resolve ? the last blitz : https://stackblitz.com/edit/nuxt-starter-swapms?file=plugins%2Fpinia.client.ts actually pinia plugins seem to be loaded on every store mount, not what I'm looking for I changed my approach : like L422Y, I use a store. The store has a internal state, where i store the ref to my IndexedDb. When I access my db, I go through a computed getter which fetch the db if it is initialized, otherwise it set it. And I use my store where need be
Want results from more Discord servers?
Add your server