Having trouble with Vue 3 Component State not updating following an asynchronous operation?

Encountering challenges in my Vue 3 app when trying to update a component's state post an asynchronous operation. Here's what's happening:

Within a component, there is a method called containerMoveHere that utilizes Socket.io for an async operation to move a container, which then gets added to the list of displayed containers. Following a successful move, I aim to update the children array in my Pinia store and trigger a re-render of the component to reflect this change.

Here's the snippet of code:

page.vue

<template>
...
<div class="flex justify-end space-x-2">
     <MoveToHereButton @click.prevent="containerMoveHere()" />
</div>
...
<div class="grid grid-cols-3 gap-4 py-6 place-content-stretch">
   <div v-for="child in children" :key="child._id">
      <ContainerCard :container="child" />
   </div>
</div>
...
</template>

<script setup lang="ts">

const userStore = useUserStore();
const containerStore = useContainerStore()
const container = storeToRefs(containerStore).container;
const children = storeToRefs(containerStore).visibleChildren;

async function containerMoveHere() {
  try {
    let containerStrId = await userStore.getContainerIdToMove();
    await containerStore.containerMoveHere(containerStrId)
  } catch (error) {
    console.error(error)
  }
}


</script>

And here's the corresponding store:

export const useContainerStore = defineStore('container', {
  state: () => {
    let container: iContainerAllType | undefined;
    const children: Array<{ visible: boolean; data: iContainerAllType }> = [];
    return { 
      container, children 
    };
  },
  getters: {
    visibleChildren(): Array<iContainerAllType> {
      return this.children.filter(c => c.visible).map(c => c.data);
    }
  },
  actions: {
   async containerMoveHere(sourceContainerStrId) {
      try {
        await socketioservice.emit('container:moveTo', {
          container: {
            Id: this.container?._id,
            Space: this.container?._space,
            SourceId: sourceContainerStrId 
            }
        });
      } catch (error) {
          console.error('Error moving container:', error);
        }
      },
   }

Additional info:

The container successfully moves, and reloading the page displays the added container within the children as expected. However, the issue lies in the fact that the children state does not update despite being a reactive property.

Appreciate any assistance you can provide on this matter.

Answer №1

Pinia simplifies working with Vue's reactive api by providing a lightweight wrapper. The key to understanding Pinia is recognizing that getters are essentially readonly computed properties. If you need to modify a computed property, you must instead update the underlying reactive data it relies on. In this case, the dependency lies with state.children, so altering this data will ultimately impact both visibleChildren and children.value.

It's important to note that Vue computeds operate in a shallow-reactive manner. This means that to trigger a re-computation of visibleChildren, the actual array referenced by this.children must be modified. Simply adjusting this.children[0].visible will not achieve the desired effect.

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

securely managing file access through lockfile.locksync in node.js

Currently, I am utilizing lockfile.locksync to secure a file in my node.js application. However, I am interested in understanding the inner workings of this utility in more detail. Despite multiple resources referring to it as a "very polite lock file util ...

Issue with $sce.trustAsResourceUrl(url) function in angularJS

Having trouble with loading a file into an iframe. Here is the code for the iframe: <iframe width="100%" height="800px" scrolling="no" ng-src="{{someUrl}}"></iframe> In the controller, I am trying to: $scope.someUrl = $sce.trustAsResourceUr ...

What is the best way to deactivate a button using AngularJS?

$scope.date = moment(currentDate); $scope.date1 = moment(currentDate).add(-1, 'days'); function checkDate(){ if ($scope.date > $scope.date1) { return true; } else{ return false; } }; checkDate(); ...

Having difficulty properly streaming UI components with Vercel's AI-SDK

Recently, I've been diving into the new Vercel's AI-SDK to expand my skills. My current project involves developing a persona generator that takes specific guidelines as inputs and generates persona attributes according to a given Zod schema. B ...

The code malfunctions following the maintenance

Recently, I started learning JavaScript and trying to improve the readability of my code by moving away from inline functions. I have a piece of code that iterates through a JSON array containing comments and then appends those comments to the DOM. Strange ...

Issue with SweetAlert2 cancel button being unresponsive while an ajax request is in progress

I have a custom function triggered when a dropdown item is selected, which triggers a sweetalert2 popup. Here's the function: function SwalPopup(ip, method) { var methodmsg = method.charAt(0).toUpperCase() + method.slice(1); swal.fire({ ...

jQuery does not function properly when used with string variables

Why am I experiencing different results in Google Chrome when using a hard-coded string versus storing the same string in a variable? While the hard-coded string works properly, the same string stored in a variable does not produce the expected outcome. ...

Using the method window.open() will launch a new window instead of opening a new tab

When the page loads, I am using JavaScript to call window.open. window.open(url, "Test Page"); Initially, it opens a new Chrome window and displays the page. However, when I use the same JavaScript code after the page has loaded, it opens the page in a n ...

Deactivate a function within Bootstrap JavaScript

Is there a way to temporarily disable a function within Bootstrap after a click event? <a href="#"><span class="glyphicon glyphicon-triangle-right" id="btn04" onclick="myfun();"></span></a> Additionally, I am looking for a soluti ...

React Side Panels that Collapse and Expand

Apologies if this task seems simple, as I am new to transitioning to React. My current application is primarily built with JavaScript, CSS, and HTML, and I am now looking to migrate it to React. There is a full-length horizontal side panel that is initiall ...

In my Cordova application, I am able to print the locally stored JSON array, but I am encountering an issue where the

Hello, I'm having some difficulties with JSON as a beginner. I've tried searching extensively but haven't found a solution that works for me. My issue arises when attempting to save data using local storage in JSON format - the array prints ...

Adding and removing dynamic fields with Bootstrap functionality

Recently, I've been trying to develop a feature where users can add and remove fields by clicking on a button. However, I've encountered a roadblock in my progress. If you take a look at this CodePen link, you'll see what I have so far. My a ...

What could be causing my middleware to run twice?

A custom middleware was created in express.js/node.js to handle session checking. If a user ID is found in the session, it displays the user's menu; otherwise, it shows the default menu. For every page request, an ID check is performed and the user d ...

tips for using a function as a parameter in a vue directive

In React and JSX, I typically use curly braces to pass nested functions and their parameters. However, in Vue.js there is a different syntax with quotes that has me feeling confused. What I am attempting to accomplish is something like the following: < ...

javascript creating unique model instances with mongoose

I've searched through related posts without finding exactly what I need. Currently, I am working on building a backend rest API and conducting tests to collect data. Each test has its own model which is associated with collections in the database. T ...

Issues with synchronizing Firebase and Node.js?

https://i.stack.imgur.com/3fwRO.png Here is the code snippet I used in my Node.js application: for(var v in sna.val()){ console.log("each "+va); console.log(v); var fourthRef = ref.child(val+'/reservation/&apos ...

Steps for raising a unique error in an asynchronous callout

As I work on making async API callouts, there might be a need to throw custom errors based on the outcome. Also, part of this process involves deleting objects from S3. try { await s3.deleteObject(bucketParams); //Since S3 API does not provide ...

Having issues making div elements with javascript

I am having trouble generating new divs when a specific div is clicked. Despite my efforts, nothing seems to be happening and the console isn't showing any errors. I've searched online for solutions but haven't found anything that addresses ...

What could be causing the Autocomplete feature to display as undefined?

I'm encountering an issue where the Autocomplete box displays "undefined" even though it returns the expected results. How can I resolve this problem? import { Drawer, List, Typography, Switch, ListItem, ListItemText, ListItemSecondaryAction, TextFiel ...

Validate if the translation file exists in ngx-translate

Is there a way to determine if a translation file exists for the language obtained from navigator.language using ngx-translate? I am looking to implement something similar to: if( isLanguageAvailable(navigator.language)) { this.translate.use(navigator.l ...