Observing the state object in Pinia does not trigger when the object undergoes changes

I am facing an issue with setting a watcher on a deeply nested object in my Pinia state.

export const useProductStore = defineStore("product", {
  state: () => ({
    attributes: {},
  }),
});

When the object has data inside it, it looks something like this:

attributes: {
  english: {
    0: {
      key: "key1",
      value: "value1"
    },
    1: {
      key: "key2",
      value: "value2"
    },
    ...
  }
}

I have tried to set a watcher on this object, but unfortunately, the watch does not trigger. Here is the component where I am attempting to do this:

<script setup>
  import { useProductStore } from "@/stores/ProductStore";
  import { storeToRefs } from "pinia";

  const productStore = useProductStore();
  const { attributes } = storeToRefs(productStore);

  watch(() => ({...attributes}), (newValue, oldValue) => {
    console.log(oldValue);
    console.log(newValue);
  }, { deep: true });
</script>

Although this code is directly from the Pinia documentation, I am not seeing any changes reflected when the state is updated. The Vue dev tools show that the state is indeed updating reactively. Can anyone help me figure out what I am missing?

Answer №1

storeToRefs generates ref()s.

The example you mentioned as coming from the Pinia documentation seems unlikely since there is no mention of spreading a ref in the official Pinia docs. If this was an error, it should be brought to Posva's attention by opening an issue on the pinia repository.

A ref can be directly watched like this:

watch(
  attributes,
  handler, 
  { deep: true }
)

...or you could watch its .value using an arrow function for finer control:

watch(
  () => attributes.value,
  handler,
  { deep: true }
)

Keep in mind that the newVal and oldVal arguments are actually Proxies. To access their underlying targets, use the toRaw function.

Here is a working demo for reference.


1 - This method allows for more focused watchers, like so:

watch(
  () => attributes.value[0]?.value),
  handler
)

2 - When placing an object in a ref(), "the object becomes deeply reactive with reactive()" (refer to details). Additionally, check out Reactive Proxy vs Original.

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

How can I put a row at full-width in a Material-UI table in React

I need assistance with displaying data in a table using JSX code: const StudentsTable = (props) => { const classes = useStyles(); return ( <TableContainer component={Paper}> <Table className={classes.table} aria-label="simple ...

Ensure to trigger the Ajax function prior to the tab change event in a Vue form wizard

I'm currently utilizing the Vue wizard from https://www.npmjs.com/package/vue-form-wizard and I need to trigger an AJAX function before the tab change event like so: beforeTabSwitch: function(tab){ if(tab===2) { this.formData .post(APP_URL ...

Activate JavaScript validation

Within each section (displayed as tabs), I have a custom validator. When one tab is active, the other is hidden. To proceed to submission, I need to disable client validation for the inactive tab. I attempt to do this by calling ValidatorEnable(, false); ...

Creating a dynamic side navigation menu that adjusts to different screen sizes

I have been working on a project's webpage that was initially created by another Software Engineer. After he left, I continued to work on the webpage. The issue I encountered is that he preferred a side menu over a navbar using the left-panel and righ ...

Zoom out the slider when scrolling

Take a look at this link and as you scroll down the page, notice how the image transitions to iPhone. Can anyone provide insight on how this effect is achieved? ...

The functionality of jQuery's appendTo method seems to be malfunctioning

I am trying to display an image with a popup using jQuery mobile. In my loop, I have the code below: for( var i = 0; i < imageArray.length; i++ ) { counter ++; // Create a new Image element var img = $('<img data-rel="popup" class=" ...

I am interested in utilizing angular 4 ng2-ui/map with places-auto-complete functionality that is restricted to a specific country

Check out my code snippet below: <input class="form-control" placeholder="Pickup Location" places-auto-complete (place_changed)="pickupChanged($event)" formControlName="pickup_location" [types]="['geocode']" /> I am trying to figure out ...

What are some techniques to enhance security when transmitting variables through a URL in JavaScript?

Instead of passing variables through a URL, I am considering implementing a method where the parameters are sent to the popup window through variables once it is opened. This would add an extra layer of security by not exposing sensitive information in the ...

Formatting Strings in JavaScript when saving as a .txt file with proper indentation

Utilizing Angular and TypeScript/JavaScript for testing purposes. Each row has been formatted with a newline at the end of the code. formattedStr += car.Name + ' | ' + car.Color + ' | ' + car.Brand + '\r\n' The da ...

How does express.route determine the route?

I have recently started learning about Node.js (specifically with Express.js) and React.js. As a result, I have some questions regarding Express Router. Let me share a portion of my code with you: server.js const app = express(); const apiRouter = requi ...

Preventing Event Propagation in JQuery Across Different Web Browsers

My GUI controls have a complex nested structure, and I need to prevent events from propagating up the DOM tree when they are clicked or changed. This functionality must be consistent across all browsers. Currently, I am using some cumbersome JavaScript co ...

Having trouble getting the JSONP request to render properly, encountering persistent errors

Need assistance with JSONP Rendering to HTML. The request is present in the source code, but I keep encountering errors on the foreach line. Any help would be greatly appreciated. <meta name="viewport" content="width=device-width, initial-scale=1"&g ...

Trouble arises with Webpack during the compilation of JavaScript files

I've been tackling a project in Laravel 5.3, smoothly using webpack until I decided to configure ES6 by adding babel packages to my npm module. This caused a code breakdown, prompting me to revert back to the initial setup. However, now every time I m ...

Tips for showcasing a Bootstrap alert

I'm attempting to integrate Bootstrap Alerts into my project, but I'm struggling to display them programmatically. Here is the HTML snippet: <div class="alert alert-success alert-dismissible fade show" role="alert" id="accepted-meal-al ...

Take the .vue files stored in the components directory and convert them into a JSON format for exporting

I am attempting to scan all .vue files within the components directory and generate a .json file in the root directory. Although my vue.config.ts file is set up as shown below, the custom method I created does not seem to be executing. function createCompo ...

Passing Object Data from Child to Parent Component in React and Leveraging its Functionality

After performing a date calculation, I stored the values of year, month, and day in an object. Now, my goal is to send this object to the parent component App.js, and then pass that data to another child component named Modal.js as a prop. I want to displa ...

Tips on updating route and content dynamically without triggering a page reload while ensuring search engine indexing compatibility

I am curious to find a way to change the URL displayed and have it reflect different content on the page, all while ensuring that it is search engine friendly for indexing by robots. I have experimented with using AJAX for dynamic data loading and angular ...

Implementing a dynamic like functionality using Ajax in Django

I've created a new structure for the like button, but it's not functioning correctly. Here are the files I'm working with: models.py class Comment(models.Model): title = models.CharField(max_length=50) author = models.ForeignKey(Pr ...

What is the best way to pause for the API response in Node JS before moving on to the next line of

When working on a node js project, I encountered a situation where I needed to call an API and wait for the response. The response is crucial as it is the output of my Alexa Skill. Check out the snippet of code for the API: const GetReportOnEmail = functi ...

Content placed in a div element via JavaScript will not wrap onto a new line

I recently created a div using JavaScript with the code mydiv.textContent="blahblahblahblahblahblah";. Although I have set the width of mydiv to 100px, the text string assigned to the div continues to run in one line without dropping down to the next lin ...