Problem with Pinia: nested array in an object

My unique store located within a vue3 application, contains an object called currentReservation with a property named pricings which is an array.

Each pricing includes an id and quantity. When I add a new pricing, it is added to both the store and component. The same goes for increasing or decreasing the quantity.

However, when I remove a pricing from the store using decreaseReservationPricing and the quantity reaches 0, the store gets updated but the storePricings property in my component does not remove the pricing. The quantity is adjusted but the object remains.

It's worth noting that even if I have initially added two pricings and then remove one, the component still displays two (although everything is working correctly in the store).

This is my component script:

<script setup lang="ts">
import { computed } from 'vue'
import { Pricing, ReservationPricing } from '@/@types/base'

import formsUiBlock from '@/components/forms/ui/Block.vue'
import CardsPricingItem from '@/components/cards/PricingItem.vue'

import { useReservationStore } from '@/stores/modules/reservation'

defineOptions({
  name: 'FormsBooking',
})

defineProps<{ pricings: Pricing[] }>()

const reservationStore = useReservationStore()
const storePricings = computed(() => reservationStore.currentReservation.pricings as ReservationPricing[]).value

function getPricingQuantity(id: string) {
  return storePricings.find(storePricing => storePricing.id === id)?.quantity || 0
}

// Manage pricing reservation quantity
function increaseReservationPricing(id: string) {
  const currentPricing = storePricings.find(pricing => pricing.id === id)

  if (!currentPricing) return storePricings.push({ id, quantity: 1 })
  currentPricing.quantity += 1
}

function decreaseReservationPricing(id: string) {
  const currentPricing = storePricings.find(pricing => pricing.id === id)

  if (currentPricing && currentPricing.quantity > 0) currentPricing.quantity -= 1
  if (currentPricing?.quantity === 0) reservationStore.cleanPricings()
}
</script>

Here is my store:

import { defineStore } from 'pinia'

// import { postReservation } from '@/api/reservation'
import { ReservationStore } from '../@types/base'
import { ReservationPricing } from '@/@types/base'

const currentReservationInit = {
  clientId: '',
  locationId: '',
  offerId: '',
  day: null,
  hours: {
    opening_hours: null,
    closing_hours: null,
  },
  firstName: '',
  lastName: '',
  email: '',
  phoneNumber: '',
  information: '',
  pricings: [],
  amount: null,
}

export const useReservationStore = defineStore('reservation', {
  state: (): ReservationStore => ({ currentReservation: currentReservationInit }),
  actions: {
    async postReservation() {
      // need to be set
    },
    cleanPricings() {
      const pricings = this.currentReservation.pricings as ReservationPricing[]
      this.currentReservation.pricings = pricings.filter(pricing => pricing.quantity !== 0)
    },
  },
})

Answer №1

One common error is immediately accessing the value, which hinders the reactivity of storePricings to changes in currentReservation.pricings, contradicting the purpose of a computed property.

The correct approach is:

const storePricings = computed(() => 
  reservationStore.currentReservation.pricings as ReservationPricing[]
)

To use it, do the following:

unref(storePricings).find(...)

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

Prevent ng-repeat from rendering the contents of my div

Currently, I am in the process of modifying a website for which I need AngularJS. I am trying to use the ng-repeat command to display some documentation on the site. However, whenever I add the ng-repeat within a div, it seems to "destroy" the layout and I ...

Creating a new Vue instance for each component, rather than using a single

Our website structure currently does not allow us to have one main app instance due to the large amount of HTML content. As a temporary solution, we are identifying the class of app and creating a new Vue instance for each component. While this method is n ...

Transferring data from JavaScript to PHP using the $.ajax method for storing information in a MySQL database

I am attempting to make a POST call from a JavaScript file to a PHP file in order to insert a variable into a MySQL database. Here are the basic files I am working with: 1° PHP file for sending the call <html> <head> <script ...

Identifying the difference between var and JSON.stringify

Take a look at this code snippet: var data = JSON.stringify({ id: _id, ReplyId: _idComment }) openDialog(_url, data, $('#div-modal1')); function openDialog(url, Id, div) { //How can we identify if variable Id is of type JSON.stringi ...

Transforming Sphere into Flat Surface

How can I convert the SphereGeometry() object into a flat plane on the screen? I want it to function in the same way as demonstrated on this website, where the view changes when clicking on the bottom right buttons. Below is the code for creating the sph ...

Can a ListItem attribute be generated?

In the realm of Material UI, you can find a detailed showcase of ListItem at http://www.material-ui.com/#/components/list The appearance of a nested ListItem is demonstrated below: <ListItem value={1} primaryText="Brendan Lim" leftAvatar={ ...

VueJS - Best practices for utilizing getters and computed properties efficiently

Vue.js has a special place in my heart, especially its computed properties and the magic of Vuex getters. However, I've reached a crossroads where I'm unsure if my current approach may be impacting performance. This pattern features prominently ...

Is it possible to invoke a Vue method during the rendering process?

Everything is performing as anticipated. This indicates that during the rendering process, the JSON data effectively converts to a CSV string as the attribute value. JSON: "functions": { "function": [ { "name": "foo" }, ...

Building forms within an AngularJS directive

I recently developed an AngularJS directive that includes a form. This form consists of a required text field along with two additional child forms. Each child form also contains a required text field. The distinguishing factor between the two child forms ...

Encountering a "Raphael is undefined" error message when working with Treant.js

I need help creating an organizational flow chart using treant.js. Below is my code snippet, but I'm encountering a 'Raphael is not defined' error that I can't seem to solve. Can someone please assist me with identifying the root cause ...

Leveraging Parameters from URL in Javascript

I'm facing an issue with my area shape, the href="/kosmetikstudios/deutschland/Bayern" tag seems to be causing a problem. I want to utilize the parameter "Bayern" (which is the last parameter in the URL). I need this to be dynamic. Below is my JavaS ...

Can Hapi-Joi validate a payload consisting of either an Array of objects or a plain Javascript object?

How can I create a schema to validate payloads for a post call that accepts either a single JS object or an array of objects to be saved in the database? JS object { label: 'label', key: 'key', help_text: 'text' } ...

Ensuring type signatures are maintained when wrapping Vue computed properties and methods within the Vue.extend constructor

Currently, I am trying to encapsulate all of my defined methods and computed properties within a function that tracks their execution time. I aim to keep the IntelliSense predictions intact, which are based on the type signature of Vue.extend({... Howeve ...

Issue with modal input causing directive template to not render

I am working on an angular-bootstrap modal where I created a custom directive to automatically focus on the input field when opened. However, after adding the directive template to my input tag, I couldn't see it when inspecting the element. Here is t ...

Concentrate on the input for the newly added item

I am currently working on a project where I have a list of items and corresponding inputs that are linked using v-for and v-model. When I click a button, a new item is added to the list. My goal is to automatically focus on the input field associated with ...

Navigational packages for React applications

As I make decisions for my React project, I am considering which routing library to choose. Are there any alternatives to "react-router," "ui-router," and "react-navigation" that you would recommend? ...

Div keydown event not being triggered in Vue

I've been struggling to get my event to fire despite following the instructions in the title. @keydown="keyPressed($event)" Although currently it looks like this, I have also attempted setting the tabIndex and adding it on mount as shown be ...

Java has trouble decoding non-ASCII characters sent through Ajax

When I send an AJAX request using jQuery post() and serialize, the encoding used is UTF-8. For instance, if 'ś' is input as a name value, JavaScript displays name=%C5%9B. Despite my attempts to set form encoding, it has not been successful. < ...

How to ensure that a Vuejs. uiv Bootstrap popover remains visible when it is being hovered over?

While I've seen similar questions regarding jQuery, my question pertains specifically to vue.js I'm utilizing uiv, which is a Vue.js Bootstrap version. Referencing the documentation, I am attempting to manually trigger a popover using trigger="m ...

ESLint detecting error with returning values in async arrow functions

Currently facing a minor inconvenience instead of a major problem. Here is the code snippet causing the issue: export const getLoginSession = async (req: NextApiRequest): Promise<undefined | User> => { const token = getTokenCookie(req) if (!t ...