Unable to update state object with action

In my Vue application, I have a product list and form. When the product list is displayed, it triggers a request to my REST API which then populates the results in a Pinia store object called products. This process works smoothly and the products are successfully added to the state.

Initially, I was using my API to fetch a single product by passing the product_id, especially for handling the product form. However, I realized that it would be more efficient to filter the existing products store object and retrieve the single product from the state rather than making another API call whenever the form component loads. To achieve this, I created a new action but unfortunately, I am struggling to get it to work properly. Below is how I defined 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 the code snippet of my product form component where I attempt to filter the products store to obtain a single product and bind it with the form:

// ProductForm.vue

<template>
 <input v-model="product.name" class="input" type="text" />
 <input v-model="product.desc" class="input" 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>

On inspecting the console.log(product), it seems like I am getting the reference to the product store object without the value property:

https://i.sstatic.net/qhl6I.png

Running all this code results in an error:

Uncaught (in promise) TypeError: $setup.product is undefined

I acknowledge that my struggle stems from my limited knowledge of Vue 3 Composition API and Pinia. I am currently unable to figure out what exactly is causing this issue.

Answer №1

After some investigation, it seems that I have identified the issue... In my ProductForm component, I was passing the prop for the product_id:

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

I was calling my action like this:

store.findProduct(props.id);

The problem arose when I realized that the prop, being a string (as it comes from the URL), may be causing the error. So, I decided to do the following:

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

This change immediately retrieved the single product into my component. Consequently, I made adjustments in my routes file to handle the parsing for me:

// @/routes/index.js

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

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Protect your website's ajax-generated content from being indexed by search engines with these strategies

Recently, Google made an update allowing its crawler to index ajax-generated content on web pages by following specific guidelines. However, my requirement is to ensure that no search engine can crawl my ajax-generated content. So, my question is: What ...

Attaching Vue.js to an HTML element using jQuery

As I develop a Chrome extension for a particular website that lacks IDs, I am resorting to using jQuery to navigate the DOM with complex queries. While studying the documentation for VueJS, I noticed it requires me to link Vue to the DOM through el: &apos ...

Displaying multiple values from a MySQL table into a textarea field using PHP loop

I currently have a value of 2 in my database +--------------+------------------+-----------+ | id_des | deskripsi | id_srt | +--------------+------------------+-----------+ | 1 | Test 4 | 4 | | 2 | ...

Communicating information to components in Next.js

I am struggling to pass the fetched data from my API to the canvas component. It appears that the data is available in the handleSubmit() function but out of scope for the canvas prop. Any help would be greatly appreciated. Thank you. I have a datepicker ...

EmberJS: Learning how to create a record with a belongsTo relationship

My issue involves using Posts and Comments to explain my problem. In my post_controller, I am trying to create a new record for a comment related to the current post. What is the recommended way to achieve this in Ember? The relationship between Post and ...

Create three-dimensional vertices in a Three.js mesh (facets)

After receiving a collection of 200+ vertices from the AutoCad API in the format of an array of vectors {X:,Y:,Z:}, I have been struggling to render them in THREE.js. Currently, my approach involves creating all possible permutations for the 200 vertices ...

Sorting elements of an array by symbol using the sort() method

Can someone assist me with sorting the element cinema in array arr by symbol unicode (the output should be "aceinm")? I am aware that I need to use the sort() method in this case. However, I am unsure of how to apply the sort method to an array element. A ...

How to redirect a form submission using jQuery

Is there a way to make this code work upon submission instead of on click? This is the form I am working with: <form> <input type="radio" name="value" value="http://google.com"><span>Google</span><br> <input type= ...

Customize Nuxt default document using a custom app.html file

According to the guidelines provided by Nuxt documentation, you have the ability to customize the default document by... placing an app.html file in the source directory of your project, which is typically the root directory. I followed these instructio ...

"Could you please refresh the mongoDB database with the latest todolist details

I have integrated a todolist feature into my frontend. You can check out a demo of it here: https://gyazo.com/a10fcd7c470439fe5cc703eef75b437f The functionality is driven by an array in a Vue component, utilizing v-models to manage the data and update the ...

Eliminating the "as" keywords from the TypeScript code

I'm looking to optimize this TypeScript code by removing the unnecessary as keywords. The code includes a method called update where I'm attempting to improve the organization of sanitizing, validating, and attributing data. However, it seems tha ...

Express session not persisting following JQuery Get request

I need to save the server variable that the user inputs. Once they submit, they are directed to another page. On this new page, I check if their server exists and redirect them back if it doesn't. When I make a post request, the session is saved, and ...

Error: Gulp task needs to have a function assigned to it at Gulp.set

Every time I attempt to execute gulp, I encounter the following error. Here is my gulpfile.js: var gulp = require('gulp'), connect = require('gulp-connect-php'), gulpPhpunit = require('gulp-phpunit'); ...

What is the best way to implement collision detection using raycasting?

For my university project, I am looking to implement collision similar to what is shown in this example. However, I am facing an issue where collision is only working on the top of the object. I referred to this for guidance. My goal is to add collision to ...

Display the focus state of ReactJS Material UI Autocomplete component by default

The Material UI autocomplete component has a stylish design when the input field is focused. You can see this on the linked page. Is it possible to set this focus state as default? In other words, can the component be loaded with this state regardless of ...

Error 404 in Laravel: Troubleshooting AJAX, JavaScript, and PHP issues

I have a dynamic <select> that depends on the value selected in another static <select>. However, I am encountering an issue: http://localhost/ajax-model?make_id=8 404 (Not Found). This problem occurs on the page where both select elements are ...

Encountering a problem with npm installation during the setup of node-sass

While attempting to run the npm install command, I encountered an error during the installation of node-sass. https://i.stack.imgur.com/qcDaA.png https://i.stack.imgur.com/YxDi2.png Here is my package.json file: { "name": "XXXXX", ...

Convince me otherwise: Utilizing a Sinatra API paired with a comprehensive JS/HTML frontend

As I embark on the journey of designing a social website that needs to support a large number of users, I have come up with an interesting approach: Implementing Sinatra on the backend with a comprehensive REST API to handle all operations on the website ...

Using jQuery to create Vertical Tabs that showcase tab content in an inline-block format

When using jQuery tabs, I recently switched to vertical tabs and noticed that the content is not positioned within the space after the tabs. Instead, it is placed inside a container div with a margin, giving the appearance of being contained within that bo ...

The menu lacks responsiveness

I'm looking to create a responsive menu on my website where the button that opens the navigation will be hidden in "desktop mode". I came across some information on w3school, but I seem to have made an error. Can you assist me with this, please? Thank ...