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

Transition smoothly with a fade-in effect as you scroll through the images, and proceed to

My Objectives: Implement a scrolling feature where images transition to the next one based on scroll movement. Create a cycle of images that automatically progress, with the view transitioning to the bottom section once all images are viewed. Currently f ...

Ways to slow down page transition on NextJs

I'm currently working on securing my private pages using a HOC withAuth. While the protection is functioning correctly, I am looking to avoid users seeing a loading screen for a split second while the access token is being retrieved from local storage ...

Issue with combining overflow-x, Firefox, and JavaScript

In Firefox, an issue arises that does not occur in other browsers. To see the problem in action, please visit this example page: -removed- Try selecting a page other than the home page. The window will scroll to your selection. You can then scroll down u ...

Technique for identifying a sequence within a longer numerical series

As I ponder this puzzle for what seems like an eternity, I humbly turn to you for a possible solution. A lengthy number resembling this one: 122111312121142113121 It is crucial to note that no numbers exceed four or fall below one. Now my quest is to une ...

choosing between different options within Angular reactive forms

I am attempting to create a select element with one option for each item in my classes array. Here is the TypeScript file: @Component({ selector: 'app-create-deck', templateUrl: './create-deck.component.html', styleUrls: [' ...

What is the best way to display a child component inside an iframe using Vue.js?

Looking to provide a live preview of an email before sending it out, I've opted to use an iframe to contain the preview and prevent style leaks. The goal is for the preview to update dynamically as the user fills out form details. How can I display a ...

Change the appearance of text with a button click using JavaScript

Currently mastering JavaScript but encountering an issue. How do I change the text to underline when clicking on "Click Me"? <p id="demo" style=" text-decoration:none; ">Hello JavaScript!</p> <button type="button" onclick="document.getE ...

Duplicate values of React object properties when using .push method within a loop

In my code, I've implemented a function called handleCreate that is responsible for taking user data and inserting it into a database. Within the loop of aliasArr.forEach(), I am sending new user instances to my database for each element in the alias ...

What is the best way to attach an event listener to detect the coordinates where a click occurs inside a div element?

Imagine a situation where you have a div container measuring 200px by 500px. The goal is to implement an event listener that can identify the x and y coordinates within this div when it is clicked. What would be the approach to achieve this in React? ...

Can you explain the contrast between onsubmit="submitForm();" and onsubmit="return submitForm();"?

Is it possible that the form below is causing double submissions? <form name="myForm" action="demo_form.asp" onsubmit="submitForm();" method="post"> function submitForm(){ document.myForm.submit(); } I've noticed a bug where sometimes two ...

Step-by-Step Guide for Uploading an Entire Folder and Its Contents

I have been working on a code to upload multiple files, but now I am facing the challenge of uploading an entire folder with multiple files and possibly subfolders containing even more files. Currently, I am utilizing JavaScript for obtaining the files and ...

Organize array elements based on their values - using javascript

I am currently exploring the most effective approach to divide an array into multiple arrays based on specific operations performed on the values within the array. Imagine I have an array like this: var arr = [100, 200, 300, 500, 600, 700, 1000, 1100, 12 ...

I designed a dropdown menu with a searchable <mat-select> feature, where selecting an item is automatic when a space bar is pressed in the search box

Description : I have implemented a dropdown list using element that contains a list of items along with a search field. This allows users to easily search for specific items in the list instead of manually scrolling through a long dropdown menu. They can ...

What is the best way to extract the date and pricing information directly from an interactive graph using Python?

My attempt to gather data from a graph using web scraping with the Selenium library was unsuccessful. The graph can be found at this link. from selenium import webdriver driver = webdriver.Chrome() driver.get('https://www.mtgprice.com/sets/Ravnica_All ...

Unable to transmit information using Postman for registration API

I have been struggling to send data via a POST request to the register API, but for some reason, the data is not being transmitted. I have tried adjusting the settings on Postman, tinkering with validation rules, and various other troubleshooting steps, ye ...

Can a script be executed on a node.js module?

I have been developing a node package with an installation script that establishes a basic application structure. This script simply creates a few folders and generates an "admin" user if one does not already exist. Currently, the script performs multiple ...

What sets apart the method of assigning event handlers using bind() versus each() in jQuery?

Could someone explain the difference between using bind() to assign event handlers and using each() for the same task? $(function () { $('someElement') .bind('mouseover', function (e) { $(this).css({ ...

What is the best way to determine if an item in an array is not empty?

Let's consider an array: arr = [{}, {}, {}, {}] If we want to determine the length of the array by counting only objects that contain at least one property, we can do this: [{}, {name: "Manchester United", odds: 3}, {}, {}] // 1 [{}, {name: "Liver ...

"Encountering a 405 error when transmitting information from an HTML file to a Python Flask server using 'GET / HTTP/1.1'

As someone who is brand new to the world of python and AJAX, I have been piecing everything together from various sources online including examples and Flask documentation. So far, I have managed to make some progress. My goal is to send latitude and longi ...

The reactivity of Vuex and Vue does not work as expected when a dictionary is used as a

What is the best approach to make a dictionary reactive as one of my store variables? Unlike an array, dictionaries are not reactive by default. Here's a minimal example I've created: Check out this example on CodeSandbox ...