Issue with Vue Composition API: Unable to append a property to an object

Currently, I am utilizing Vue's Composition API in my project. However, I have encountered an issue where the template renderer does not recognize changes when I add a property to a ref object. Below is the code snippet that demonstrates this problem:

<template>
  <div id="app">
    <button @click="updateObj">Click</button>
    <div v-if="obj[1]">{{ obj[1] }}</div>
  </div>
</template>

<script>
import { defineComponent, ref } from "@vue/composition-api";

export default defineComponent({
  name: "App",
  setup() {
    const obj = ref({});

    const updateObj = () => {
      obj.value[1] = "hello";
      console.log(obj.value);
    };

    return {
      obj,
      updateObj,
    };
  },
});
</script>

Upon clicking the button which triggers the updateObj function, the property "1" of the obj object is set to "hello". The expected behavior is to see "hello" displayed in the browser if obj[1] is set, but no text is rendered. You can view a demo here on CodeSandbox.

As someone who has been working with the Composition API for quite some time now, this issue perplexes me. I have attempted using reactive instead of ref, but unfortunately, the problem still persists.

Answer №1

When working with primitive values, it's recommended to use ref. For objects, you should utilize reactive. The official documentation explains this concept:

If using ref, we are essentially converting style (1) into a more detailed version using refs to make the primitive values reactive.

  • Using reactive is very similar to style (2). Simply create the object with reactive and you're done.
  • Using reactive is very similar to style (2). Simply create the object with reactive and you're done.

...
Use ref and reactive in a manner similar to declaring primitive type variables and object variables in regular JavaScript. It's advisable to implement a type system with IDE support when adopting this approach.

To ensure reactivity, directly assign the object to the ref's value :

 obj.value = { 1: "hello" };

VIEW LIVE DEMO

Answer №2

I'm leaving my response here for future reference - next time I search, it will be right here.

If you're utilizing the composition api alongside Vue 2, make sure to utilize set when adding a new tracked property to an object.

Resource: https://github.com/vuejs/composition-api

⚠️ set and del workaround for adding and deleting reactive properties ⚠️ Note: set and del are not available in Vue 3. We offer them as a solution here due to the constraints of Vue 2.x reactivity system.

In Vue 2, calling set is necessary to track new keys on an object (similar to Vue.set but for reactive objects created using the Composition API). Conversely, in Vue 3, they can simply be assigned like regular objects.

Additionally, in Vue 2, calling del ensures that deletion of a key triggers view updates in reactive objects (similar to Vue.delete but for reactive objects created with the Composition API). In Vue 3, deletions can be done by calling delete foo.bar.

<template>
  <div id="app">
    <button @click="updateObj">Click</button>
    <div v-if="obj[1]">{{ obj[1] }}</div>
  </div>
</template>

<script>
import { defineComponent, ref, set } from "@vue/composition-api";

export default defineComponent({
  name: "App",
  setup() {
    const obj = ref({});

    const updateObj = () => {
      set(obj.value, 1, "hello");
      console.log(obj.value);
    };

    return {
      obj,
      updateObj,
    };
  },
});
</script>

LIVE DEMO

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

Obtain a string in JSON format upon clicking in Angular 2

I am working on extracting the title from a json response using a click event. Currently, I can retrieve all the titles when the button is clicked, but I am looking for a way to obtain a specific title based on the button or a href that the user has clicke ...

Is it possible to utilize a JavaScript variable in this particular scenario and if so, what is the

let myVariable = <?php echo json_encode($a[i want to insert the JS variable here]); ?>; Your prompt response would be highly valued. Many thanks in advance. ...

Struggling to integrate a functional update button into my Material UI datagrid version 5.6.1

I'm facing a challenge in adding a button to the rows of my Material UI DataGrid component. Here is my DataGrid component setup: <DataGrid rows={adminStorage} columns={columns} autoPageSize getRowId={(logistics) => logistics._id ...

Trouble with updating the view when an array is modified in ng-repeat? It seems like using $scope.$apply() may not

When updating the array inside a function, the view does not automatically update. However, if you use console.log to check the array after pushing values, it shows the updated array. Even trying $scope.apply() inside $timeout did not solve this issue. Ja ...

Is it possible to refresh the chat-box using PHP?

I recently created a chat box application using PHP, but I'm facing an issue with its automatic reload functionality. Is there a way to implement auto-reload in PHP itself, or would it be better to restructure the system to utilize AJAX? Additionally, ...

Smoothly automate horizontal scrolling using JavaScript

My programming journey involved creating a code snippet that automatically scrolls paragraphs horizontally, giving it the appearance of "Breaking News" updates on popular websites. The Javascript script I implemented performs automatic scrolling, but once ...

Analyzing a text file against a string to identify discrepancies using Node.js

Recently, I came across a dilemma involving a text file containing information on all Wifi connections (such as ssid, mac no, strength, etc.) that were within my laptop's range just 2 minutes ago. Now, I've rerun the code and obtained the current ...

Obtain date and currency formatting preferences

How can I retrieve the user's preferences for date and currency formats using JavaScript? ...

What could be causing these strange white lines to show up on my AFrame meshes?

When I import a GLB scene with baked textures into A-Frame using THREE.js, I am experiencing an issue where white lines appear on my objects (pictured below). The walls are grouped meshes which may explain the lines appearing there, but I am puzzled as to ...

The specified type '{ state: any; dispatch: React.Dispatch<{ type: string; value: any; }>; }' is not compatible with the expected type

I've been working on a UI layout that includes checkboxes on the left, a data table on the right, and a drop zone box. The aim is to keep the table data updated whenever a new file is dropped, and also filter the data based on checkbox selection. I ma ...

Create a typescript class object

My journey with Typescript is just beginning as I delve into using it alongside Ionic. Coming from a background in Java, I'm finding the syntax and approach quite different and challenging. One area that's giving me trouble is creating new object ...

Issues with Implementing Scroll Directive in Angular JS

Apologies for asking what may seem like a silly question. I'm still new to using AngularJS and recently came across a neat little scroll directive on http://jsfiddle.net/88TzF/622/. However, when I tried implementing the code in the HTML snippet below ...

What happens to CSS specificity when JavaScript is used to change CSS styles?

When JavaScript modifies CSS, what is the specificity of the applied styles? For example: document.getElementById("demo").style.color = "red"; Would this be deemed as inline styling? ...

Retrieve the scrollTop, scrollLeft properties, and other scroll-related data from an element using Selenium

When testing a Python/Django element that is scrolled using scrollTop, I am trying to retrieve the value of scrollTop. In JavaScript, I can access this value with: element.scrollTop I attempted to do this in Python using: element.get_attribute('sc ...

When I attempt to press the shift + tab keys together, Shiftkey is activated

Shiftkey occurs when attempting to press the shift + tab keys simultaneously $("#buttonZZ").on("keydown",function (eve) { if (eve.keyCode == 9 && eve.shiftKey) { eve.preventDefault(); $("#cancelbtn").focus(); } if (eve. ...

Problem with Ajax causing full-page reload

I currently have a webpage that utilizes JqueryUI-Mobile (specifically listview) in conjunction with PHP and some Ajax code. When the page loads initially, it displays a list generated from a MySQL DB. I want this list to refresh itself periodically witho ...

Steer clear of using relative public paths in Vue applications

Within my vue.config.js file, I have set the publicPath as shown below: publicPath: '/mobile' I have a logout button that needs to link to a URL outside of the publicPath I defined: <v-btn text small color="teal" to="/a ...

creating a fresh instance of a class while in a subscribe method

Although this code is functional, it briefly displays incorrect data because a blank token is instantiated before being populated in the subscribe function. Is there a way to move the instantiation into the subscribe function or provide all necessary par ...

Is there a more efficient method to tally specific elements in a sparse array?

Review the TypeScript code snippet below: const myArray: Array<string> = new Array(); myArray[5] = 'hello'; myArray[7] = 'world'; const len = myArray.length; let totalLen = 0; myArray.forEach( arr => totalLen++); console.log(& ...

Guide to emphasizing a specific term within a string by utilizing coordinates in javascript

I am facing a challenge when trying to highlight multiple words within a sentence. Specifically, I have text data that looks like this: "The furnishing of Ci Suo 's home astonished the visitors: a home of 5 earthen and wooden structures, it has a sit ...