Home > Software engineering >  Can't set state object using action
Can't set state object using action

Time:12-20

I have a product list and form on my vue application. When the product list is opened, a request is made to my rest api and fills the results in a pinia store object (products). This works great so far and the products get added to my state.

I can also request a single product using my api by passing the product_id to it. This is how I handled the product form at first, but realized it would be more efficient to filter the products store object and get the single product from state rather than make another api request when the form component loads. I created a new action to do just this but I can't get it to work. Here is my store with the action:

//ProductStore.js

import { defineStore } from "pinia";
import { getProducts } from "@/composables/products";

export const useProductStore = defineStore("product", {
  state: () => ({
    products: [], //for my products list component
    product: {}, //for my product form component
    attributes: [],
    loading: false,
    error: "",
  }),
  actions: {
    findProduct(id) { //find single product in store
      this.product = this.products.find((product) => product.id === id);
    },
    async fetchProducts() { // retrieve all products from api
      this.loading = true;
      const { products, error } = await getProducts(); //api call
     
      this.products = products;
      this.error = error;
      this.loading = false;

    },
  }
});

Here is my product form component I'm trying to filter the products store to get a single product and bind with the form:

// ProductForm.vue

<template>
 <input v-model="product.name"  type="text" />
 <input v-model="product.desc"  type="text" />
</template>

<script setup>
  import { onMounted } from "vue";
  import { storeToRefs } from "pinia";
  import { useProductStore } from "@/stores/ProductStore";
  
  const props = defineProps({
    id: String,
  });

  const store = useProductStore();
  const { product, error, loading } = storeToRefs(store);

  onMounted(() => {

    store.findProduct(props.id);
    console.log(product);

  });
  
</script>

When I console.log(product) it appears I get the ref() to the product store object but without the value property:

enter image description here

When I run all of this I get the error: Uncaught (in promise) TypeError: $setup.product is undefined

I'm completely aware this is due to my poverty of knowledge with vue 3 composition API and pinia. I can't figure out what is going on.

CodePudding user response:

Well I think I figured it out... in my ProductForm component I was bringing in the prop for the product_id:

const props = defineProps({
    id: String,
  });

And I was invoking my action like this:

store.findProduct(props.id);

I started wondering if the prop being a string (since it comes from url) was causing the issue. So I used:

store.findProduct(parseInt(props.id));

which immediately returned the single product into my component. So I ended up modifying my routes file to handle the parse for me:

//  @/routes/index.js

{
  name: "Product",
  path: "/products/:id",
  component: () => import("@/components/ProductForm"),
  props: route => ({ id: Number(route.params.id) }),
},
  • Related