N
Nuxt7mo ago
Wild

Is it possible to initialize store state with async function ?

Hello friends, I am trying to set up my store from indexedDb. I've seen an example with useLocalStorage from vueUse, but how can I make it works with custom function ? Thank for the help
5 Replies
Wild
WildOP7mo ago
import { skipHydrate } from "pinia";
const key = "item";

export const useItemStore = defineStore(key, {
state: () => ({
itemtypes: new Map(),
fetching: false,
}),
actions: {
async fetch() {
return new Promise(async function (resolve, reject) {
if (process.client) {
console.log("process client");
const db = await getIdb.value;
console.log(db);
const data_trans = db
.transaction("test")
.objectStore("test")
.get(key);
data_trans.onsuccess = async (event) => {
try {
console.log("success");
let buffer = data_trans.result;
console.log(buffer);

resolve(
new Map<number, string>(
buffer.map((raw) => {
return [raw.id, raw.title];
})
)
);
} catch (error) {
console.log("error", error);
const buffer: any = await $fetch(
`https://jsonplaceholder.typicode.com/posts/`,
{
headers: { "Content-Type": "application/json" },
method: "GET",
}
);
db.transaction("test", "readwrite")
.objectStore("test")
.put(buffer, key);
resolve(
new Map<number, string>(
buffer.map((raw) => {
return [raw.id, raw.title];
})
)
);
}
};
data_trans.onerror = async (event) => {
console.log(data_trans.error);
};
}
});
},
hydrate(state, initialState) {
console.log("hydrating !!!");
this.actions.fetch().then((value) => (state.itemtypes = value));
},
});
import { skipHydrate } from "pinia";
const key = "item";

export const useItemStore = defineStore(key, {
state: () => ({
itemtypes: new Map(),
fetching: false,
}),
actions: {
async fetch() {
return new Promise(async function (resolve, reject) {
if (process.client) {
console.log("process client");
const db = await getIdb.value;
console.log(db);
const data_trans = db
.transaction("test")
.objectStore("test")
.get(key);
data_trans.onsuccess = async (event) => {
try {
console.log("success");
let buffer = data_trans.result;
console.log(buffer);

resolve(
new Map<number, string>(
buffer.map((raw) => {
return [raw.id, raw.title];
})
)
);
} catch (error) {
console.log("error", error);
const buffer: any = await $fetch(
`https://jsonplaceholder.typicode.com/posts/`,
{
headers: { "Content-Type": "application/json" },
method: "GET",
}
);
db.transaction("test", "readwrite")
.objectStore("test")
.put(buffer, key);
resolve(
new Map<number, string>(
buffer.map((raw) => {
return [raw.id, raw.title];
})
)
);
}
};
data_trans.onerror = async (event) => {
console.log(data_trans.error);
};
}
});
},
hydrate(state, initialState) {
console.log("hydrating !!!");
this.actions.fetch().then((value) => (state.itemtypes = value));
},
});
manniL
manniL7mo ago
1) I'd go for setup stores 2) Then expose an async init function 3) call the init function on the server side (just once) if you need SSR
Wild
WildOP7mo ago
when you say a init function, is it like literally a function named init ? Since I want to check the indexedDb only on the client, I've had some issue with the hydration. when I use skipHydrate, I have a cannot stringify non pogo error
manniL
manniL7mo ago
can be named as you want
Wild
WildOP7mo ago
Well not sure why it works, but it seems to work perfect with either hydration and mount and ssr.
import { skipHydrate } from "pinia";
import { useAsyncState } from "@vueuse/core";
const key = "job";

export const useJobStore = defineStore(key, () => {
const { state, isReady, isLoading } = useAsyncState(
ifetch().then((data) => data),
{ id: null }
);
async function ifetch() {
return new Promise(async function (resolve, reject) {
if (process.client) {
console.log("process client");
const db = await getIdb.value;
console.log(db);
const data_trans = db.transaction("test").objectStore("test").get(key);
data_trans.onsuccess = async (event) => {
try {
console.log("success");
let buffer = data_trans.result;
console.log(buffer);

resolve(
new Map<number, string>(
buffer.map((raw) => {
return [raw.id, raw.title];
})
)
);
} catch (error) {
console.log("error", error);
const buffer: any = await $fetch(
`https://jsonplaceholder.typicode.com/posts/`,
{
headers: { "Content-Type": "application/json" },
method: "GET",
}
);
db.transaction("test", "readwrite")
.objectStore("test")
.put(buffer, key);
resolve(
new Map<number, string>(
buffer.map((raw) => {
return [raw.id, raw.title];
})
)
);
}
};
data_trans.onerror = async (event) => {
console.log(data_trans.error);
};
}
});
}
return { state};
});
import { skipHydrate } from "pinia";
import { useAsyncState } from "@vueuse/core";
const key = "job";

export const useJobStore = defineStore(key, () => {
const { state, isReady, isLoading } = useAsyncState(
ifetch().then((data) => data),
{ id: null }
);
async function ifetch() {
return new Promise(async function (resolve, reject) {
if (process.client) {
console.log("process client");
const db = await getIdb.value;
console.log(db);
const data_trans = db.transaction("test").objectStore("test").get(key);
data_trans.onsuccess = async (event) => {
try {
console.log("success");
let buffer = data_trans.result;
console.log(buffer);

resolve(
new Map<number, string>(
buffer.map((raw) => {
return [raw.id, raw.title];
})
)
);
} catch (error) {
console.log("error", error);
const buffer: any = await $fetch(
`https://jsonplaceholder.typicode.com/posts/`,
{
headers: { "Content-Type": "application/json" },
method: "GET",
}
);
db.transaction("test", "readwrite")
.objectStore("test")
.put(buffer, key);
resolve(
new Map<number, string>(
buffer.map((raw) => {
return [raw.id, raw.title];
})
)
);
}
};
data_trans.onerror = async (event) => {
console.log(data_trans.error);
};
}
});
}
return { state};
});
Thanks for the advice ! I watched a lot of your useFetch & co video, it helped me a lot ! thanks for that also
Want results from more Discord servers?
Add your server