Skip to main content

Define store using pinia in vuejs with hot reload support

· 2 min read
Hreniuc Cristian-Alexandru

Check below how to define the store, to access it, you ca do this:

const store = useCompanyEventsStore();

store.sorted;
store.events;

You will notice that the store calls a method every X seconds to get the new data from the server, to keep it up to date(using reload method).

You can define your store like this:

import { ref } from "vue";
// Service
import CompanyService from "src/service/company/Company";
import notify from "src/service/notify";
// Store
import { defineStore, acceptHMRUpdate } from "pinia";
//
import settings from "src/conf/settings";
import EventInfo from "src/models/responses/employee/EventInfo";

export const useCompanyEventsStore = defineStore("companyEvents", () => {
// State
const events = ref(new Array<EventInfo>());
const loading = ref(false);

let _autoReload: NodeJS.Timeout | undefined = undefined;
let smallestId = 0;
let biggestId = 0;
let employeeId = 0;
let siteId = 0;

// Getters
const sorted = computed( () => events.value.sort(smt));
// Actions
function setEmployeeId(id: number) {
employeeId = id;
}

function setSiteId(id: number) {
siteId = id;
}

async function load() {
loading.value = true;
await CompanyService.events.get(employeeId, siteId).then(
(eventsResponse) => {
events.value = [...eventsResponse];
events.value.forEach((element) => {
element.new = false;
});
if (events.value.length !== 0) {
biggestId = events.value[0].id;
smallestId = events.value[events.value.length - 1].id;
}
enableReload();
},
(error: Error) => notify.error(error.toString())
);
loading.value = false;
}

async function reload() {
await CompanyService.events.reload(biggestId, employeeId, siteId).then(
(eventsResponse) => {
const newEvents = [...eventsResponse];
events.value.forEach((element) => {
element.new = false;
});
newEvents.forEach((element) => {
element.new = true;
});
// Append them at the start of the list.
if (newEvents.length !== 0) {
events.value = newEvents.concat(events.value);
}
if (events.value.length !== 0) {
biggestId = events.value[0].id;
smallestId = events.value[events.value.length - 1].id;
}
},
(error: Error) => notify.error(error.toString())
);
}

function disableReload() {
if (_autoReload) {
clearInterval(_autoReload);
_autoReload = undefined;
}
}

function enableReload() {
if (!_autoReload) {
_autoReload = setInterval(function () {
load();
}, settings.company.events.reloadInterval);
}
}

function reset() {
events.value = new Array<EventInfo>();
loading.value = false;
smallestId = 0;
biggestId = 0;
employeeId = 0;
siteId = 0;
disableReload();
}

return {
events,
loading,
sorted,
setEmployeeId,
setSiteId,
disableReload,
enableReload,
load,
reload,
reset,
};
});

if (import.meta.hot) {
import.meta.hot.accept(
acceptHMRUpdate(useCompanyEventsStore, import.meta.hot)
);
}