Unraveling the intricacies of extracting data from nested object properties

Why do my variables stop being reactive after unwrapping from props?

I have three components - a parent component, a second component for display, and a third component for updating data based on input (simplified code here).

The third component updates the parent through an event, and that updated value should be passed to the child. I understand that the architecture might not be ideal as I'm not using any store.

I would expect the emit to update the value and the new value to be displayed on Child1. This works when I don't unwrap the prop.

// Parent.vue
<template>
  <ChildA :data="data"/>
  <ChildB @update-data="updateData"/>
</template>
<script setup>
import { reactive, toRefs } from "vue";
const { data } = toRefs(
  reactive({ data: { latestEvent: { status: "fail" } } })
);

const updateData = (event) => {
  data.value = event;
};
</script>
// ChildA.vue
<template>
  {{ latestStatus }}
</template>
<script setup>
import { computed, toRefs } from "vue";

const props = defineProps({
  data: {
    type: Object,
    default: () => {},
  },
});
const { data } = toRefs(props);
const { latestEvent } = data.value;
const latestStatus = computed(() => data.value.latestEvent.status);
// const latestStatus = computed(() => latestEvent.status); THAT'S NOT REACTIVE
</script>
// ChildB.vue
<template>
  <select v-model="status" @change="onChange()">
    <option value="in progress">in progress</option>
    <option value="new">new</option>
    <option value="fail">fail</option>
  </select>
</template>
<script setup>
import { reactive, ref, toRefs } from "vue";
const status = ref("");
const emit = defineEmits(["updateData"]);

const onChange = () => {
  emit(
    "updateData",
    toRefs(
      reactive({
        latestEvent: { status: status },
      })
    )
  );
};
</script>

How can I make my variables reactive after unwrapping them from the prop?

I would think something like this could work:

const { data } = toRefs(props);
const { latestEvent } = toRefs(data);

Answer №1

When the entire data is modified and not just the value of data.latestEvent.status, prematurely destructuring it as

const { latestEvent } = data.value
will deactivate reactivity. The reference to latestEvent points to the data.latestEvent object that existed when the setup function was executed.

In essence, what occurs here is:

let foo = { bar: { baz: 1 } };
let bar = foo.bar;
let baz = foo.bar.baz;
foo.bar = { baz: 2 };
console.log(bar !== foo.bar); // true
console.log(baz === 1); // true

The best practice is always:

const latestStatus = computed(() => data.value.latestEvent.status);

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

Updating an object with AngularJS

Let's consider the code snippet below: var absenceType = {name: 'hello'}; this.newAbsenceType = angular.copy(absenceType); After making changes to this.newAbsenceType, you want to apply these changes to the original object. I have explore ...

What is the best way to manage photos from your phone without having to upload them online?

I'm currently developing an application using AngularJS/Javascript, HTML, and CSS within a cloud-based environment on c9.io. My next task is to create and test an app that can access the phone's photo album, apply filters to images, and I'm ...

Storing a credit card number securely using Stripe in a MERN stack application

Currently, I am working on an application using the MERN stack where users can create companies. Each company requires various details such as name, address, phone number, email, and credit card information including the 16-digit card number, expiration da ...

What are the best ways to personalize my code using Angular Devextreme?

Our development team is currently utilizing Angular for the front-end framework and ASP.net for the back-end framework. They are also incorporating Devextreme and Devexpress as libraries, or similar tools. However, there seems to be difficulty in implement ...

Tips on how to modify database records rather than generating new ones

Currently, my team is developing a web application that utilizes wearables to monitor vital parameters. As part of our integration testing, we are using a Fitbit device. The app itself is built with Angular and JavaScript, while the database is hosted on C ...

What is the best way to connect input values with ngFor and ngModel?

I am facing an issue with binding input values to a component in Angular. I have used ngFor on multiple inputs, but the input fields are not showing up, so I am unable to push the data to subQuestionsAnswertext. Here is the code snippet from app.component ...

Contrary to expectations, the middleware EJS fails to render JPG files at

I am currently working on a NodeJS server using EJS. The goal of this server is to render an HTML page that contains a line of text and a jpg file. However, I am encountering an issue with the jpg file not being loaded by the server. Even though I have sp ...

What is the jQuery syntax for targeting a specific element within an object?

Is there a way to access a sub element from $(this)? For instance, how can I specifically select a span element inside the this object? ...

Subscriber client successfully activated and operational via the command line interface

I have incorporated a script into my PHP file that reads the Pusher channel and performs various actions when a new event occurs on the specified channel. If I access the following URL in my browser: http:/localhost/pusher.php and keep it open, the p ...

update value asynchronously

My implementation involves a dialog controller: .controller('loadingDialogCtrl', function($scope, $mdDialog, $rootScope, loadingDialog) { $scope.loadingDialog = loadingDialog; }); In another controller, I use the dialog controller and manip ...

Is there a way to create a function in JavaScript that eliminates duplicate Objects within an Array of Objects?

Currently, I'm working on a function to store details of a couch in a JS object with 3 properties locally. The properties include: An ID (obtained from the product URL using a function) A color (retrieved through an event listener) A quantity ...

Tips for stacking objects vertically in mobile or tablet view using HTML and CSS

I have been diligently working on a project using a fiddle, and everything appears to be running smoothly in desktop view. The functionality is such that upon clicking any two product items (with one remaining selected by default), a detailed description ...

Leveraging global variables within Vuex state management strategy

I have successfully added custom global variables into Vue by injecting them. Here is the code snippet: export default function (props, inject) { inject('models', { register(name) { const model = require(`@/models/${name}. ...

The components for my children are not being displayed within the Drawer component in Material UI and React

Why are the Material UI components and other project components not displayed when I use my DrawerForm component? List of dependencies: react: 18.2.0 react-dom: 18.2.0 @amcharts/amcharts5: 5.3.6 @mui/icons-material: 5.11.11 @mui/material: 5.11.12 Code s ...

Step by step guide on showcasing live server information obtained from the user-end through AJAX technique in a Javascript Pie Chart, within an ASP.NET html template

I have successfully managed to transfer data from the Client Side (C# Back End) to Server Side (JavaScript HTML in aspx) using AJAX. I need help figuring out how to display my own data dynamically in a JavaScript Pie Chart instead of hardcoding values. He ...

Encountered an Uncaught ChunkLoadError with Vercel Next.js: Chunk 0 failed to load

Upon removing the node modules and package-lock.json files, I encountered the error mentioned above when attempting to reload any page. The project works fine after being restarted for the first time. However, upon reloading the page again, it displays a b ...

I possess an image sourced from the backend, and I have added boxes on top of it. However, I am struggling to accurately place these boxes on the specific points that I desire

I'm struggling to scale the image to fit my container's width and height in order to properly position specific points. Unfortunately, I've been unable to achieve this so far. Check out my code below: <div class="img-magnifier-cont ...

Can we achieve live map updates in real time using Google API with Node.js technology?

Can Google Maps API in conjunction with Node.js provide truly real-time updates on a map without any callback limits, or does Google enforce restrictions such as a 5 second or 30 second time frame? Node.js is known for its ability to handle almost real-ti ...

Guide to dynamically setting the title and background color of the navigation bar in React Navigation 5

In my current project, I am utilizing React Navigation Bar version 5 and have successfully set the title in App.js. However, I now need to change this title dynamically when the screen is rendered. I attempted to use this.props.navigation.navigate('Ex ...

What is the reason for Nightwatch running each .js file as a Child process? Could it be due to alterations in the configuration settings

Recently, I've been experiencing an issue when running Nightwatch.js where my console is spawning child processes for every .js file in each folder and subfolder. Multiple Chrome instances are opening along with them and even the module folders with r ...