Dan Nakatoshi
Dan Nakatoshi

Reputation: 23

Vue3 - How to invoke a function on App.vue from any components / axios / Pinia

I have a question regarding the vue3 coding structure and wanted to know the best approach to achieve the targetbelow.

repository: https://github.com/TraitOtaku/crudapp-vue3

Office.vue: To load the main Office view(page), fetch the office data from API and store in the office.js(Pinia)

OfficeForm.vue: Template for CRUD form for Office data. Clicking OK button will update the data. I also wanted to trigger the popup(toast) if Axios returns success.

office.js:Pinia file that stores office data fetched by Axios

https://github.com/TraitOtaku/crudapp-vue3/blob/master/src/views/admin-views/team/Office.vue https://github.com/TraitOtaku/crudapp-vue3/blob/master/src/components/layout-ui/form/member/OfficeForm.vue

I use this PrimeVue UI library (https://primefaces.org/primevue/toast) and wanted to invoke the Toast popups from any components.

Target: I have this toast component from PrimeVue UI library on the App.vue

<template>
  <LayoutView></LayoutView>

  <!-- POP UP MESSAGE -->
  <Toast position="bottom-left" />
</template>

in App.vue <script setup> :

const showSuccess = () => {
  toast.add({
    severity: "success",
    summary: "Success Message",
    detail: "Message Content",
    life: 3000,
  });
};

const showError = () => {
  toast.add({
    severity: "warn",
    summary: "Error Occurred",
    detail: "Something went wrong",
    life: 3000,
  });
};

Question: How can I invoke the showSuccess() and showError() from any child components?

My idea 1: Use Provide/Inject and send the showSuccess() and showError() to Pinia store and invoke each function after the Axios response. -> Seems to be difficult to implement the inject() in .js file.

My idea 2: Use $root$emit to invoke the App.vue's showSuccess() and showError(). -> I have no idea how to receive the emmited $root$emit from App.vue file.

My idea 3: Store the value (i.g. createdData = ref(0) ) and createdData++ when Axios returns success. create a watcher in the App.vue file and invoke showSuccess() when createdData.value changes

Note: I just don't want to repeat this component everywhere in the Vue application.

Please advise. Thank you!

Upvotes: 0

Views: 1143

Answers (1)

Dan Nakatoshi
Dan Nakatoshi

Reputation: 23

Simply I added the toast function and it worked!

import { defineStore } from "pinia";
import { ref, toRaw, inject } from "vue";
import EventService from "@/plugins/EventService";
import { useToast } from "primevue/usetoast";

export const useOfficeStore = defineStore("office", () => {
  const toast = useToast();
  const data = ref(null);

  const getData = () => {
    EventService.getOffice()
      .then((response) => {
        data.value = response.data;
      })
      .catch((error) => {
        console.log("data:" + error);
        toast.add({
          severity: "warn",
          summary: "Network Error",
          detail: "Database connection error",
          life: 3000,
        });
      });
  };
  getData();

  const updateData = (formState, id) => {
    EventService.updateOffice(id, toRaw(formState))
      .then((response) => {
        console.log("Office Updated" + response.data);
        getData();
        toast.add({
          severity: "info",
          summary: "Data Created",
          detail: "Office Data was successfully updated",
          life: 3000,
        });
      })
      .catch((error) => {
        console.log(error);
        getData();
        toast.add({
          severity: "error",
          summary: "Error Occurred",
          detail: "Data was not updated",
          life: 3000,
        });
      });
  };

  return {
    data,
    getData,
    updateData,
  };
});

Upvotes: 1

Related Questions