Reputation: 177
I'm currently working on a project where to fetch data from an API. I need access to that data all over my app, so I thought that the best option was to use Pinia (usually I used Vuex, but I want to try this "new" store solution).
My "problem" is that I really don't know if the way I achieve my goal is the best way or even a "good practice". In my Pinia store I wrote this:
export const listadoADPs = defineStore("listado", {
state: () => ({
adps: [],
}),
actions: {
getADPs() {
const api =
"URL";
fetch(api)
.then((response) => response.json())
.then(({ data }) => (this.adps = data))
.catch((error) => console.log(error));
},
},
});
Then, in my component I coded this:
<script setup>
import { ref, computed } from "vue";
import { listadoADPs } from "@/stores/adps";
const store = listadoADPs();
const cards = ref([
{
number: computed(() => store.adps.length),
description: "ADPs vigentes",
},
{
number: computed(
() => store.adps.filter((adp) => adp.estado_cd === "Suscrito").length
),
description: "Convenios de Desempeño Suscritos",
},
{
number: 0,
description: "Alertas enviadas",
},
]);
</script>
Specifically, I don't know if making a computed property for each "number" key in my array "cards" is right, I mean, finally is the same data, so why I can't make just one computed property and save the data in a variable? The thing is that if I work in that way when I reloaded the page, the data just disappears.
Reading the documentation and much more, I think there is a reactivity issue that I still don't understand at all, but I really want to make well this code, so I prefer to ask to you.
Upvotes: 14
Views: 24388
Reputation: 4539
I would use getters here.
// store.ts
export const listadoADPs = defineStore("listado", {
state: () => ({
adps: [],
}),
actions: {
getADPs() {
const api =
"URL";
fetch(api)
.then((response) => response.json())
.then(({ data }) => (this.adps = data))
.catch((error) => console.log(error));
},
},
getters: {
// BEWARE: getter names cannot be same as state props!
listadoADPs(state) {
return state.adps.length;
},
adpsFilteredLength(state) {
return (query: string) => state.adps.filter((adp) => adp.estado_cd === query).length;
}
},
});
in your component
<script setup>
import { ref, computed } from "vue";
import { listadoADPs } from "@/stores/adps";
const store = listadoADPs();
const cards = ref([
{
number: store.adpsLength,
description: "ADPs vigentes",
},
{
number: computed( // must be computed because of sending parameter
() => store.adpsFilteredLength("Suscrito")
),
description: "Convenios de Desempeño Suscritos",
},
{
number: 0,
description: "Alertas enviadas",
},
]);
</script>
For persistency this Pinia plugin seems to be nicely done: https://www.npmjs.com/package/pinia-plugin-persist
As others already mentioned I can't help you more without providing more information.
Idealy post reproduciton of your problem ;)
Upvotes: 7