Is there a native feature in Vue.js that allows for the addition of a duplicate of a constantly saved object to an array that is repeated

Having an issue with my Vue.js app where adding a newItem to a list of items results in the added object being bound to the input. Here's what I've tried so far:

new Vue({
  el: '#demo',

  data: {
    items: [
      {
        start: '12:15',
        end: '13:15',
        name: 'Whatch Vue.js Laracast',
        description: 'Watched the Laracast series on Vue.js',
        tags: ['learning', 'Vue.js', 'Laracast', 'PHP'],
        note: "Vue.js is really awesome. Thanks Evan You!!!"
      },
      {
        start: '13:15',
        end: '13:30',
        name: "Rubik's Cube",
        description: "Play with my Rubik's Cube",
        tags: ['Logic', 'Puzzle', "Rubik's Cube"],
        note: "Learned a new algorithm."
      }
    ],
    newItem: {start: '', end: '', name: '', description: '', tags: '', note: ''}
  },

  methods: {
    addItem: function(e) {
      e.preventDefault();

      this.items.push(this.newItem);
    }
  }
});

Although pushing the object as is onto the array works, it remains bound to the input causing issues. Desired outcome is to add a copy of the object that won't change when the input does. Check out this this fiddle. One way I found solution is by doing:

addItem: function(e) {
  e.preventDefault();
  this.items.push({
    name:        this.newItem.name,
    start:       this.newItem.start,
    end:         this.newItem.end,
    description: this.newItem.description,
    tags:        this.newItem.tags,
    notes:       this.newItem.notes
  })
}

This alternative method however involves a lot of repetitions.

The main question: Is there any built-in functionality within Vue.js to add just a copy of the object instead of persisting the original object?

Answer №1

Take a look at this particular issue on GitHub.

Surface-Level Replication

I had been utilizing jQuery's $.extend until I learned from Evan You about an unpublicized built-in extend function Vue.util.extend that accomplishes surface-level replication. Here is an example of how you can apply it:

addItem: function(e) {
  e.preventDefault();

  this.items.push(Vue.util.extend({}, this.newItem));
}

View the revised Fiddle for demonstration.

In-Depth Replication

When performing a surface-level clone on an object that contains references to other objects, you are actually duplicating the references to those external objects rather than cloning them. To fully replicate the object, you need an In-Depth Clone.

For an in-depth clone, as Evan mentioned in the initial link, one could utilize:

JSON.parse(JSON.stringify(object))
. This difference can be observed between this fiddle and this fiddle.

If you are using lodash, explore lodash cloneDeep. For NPM users, consider checking out clone-deep.

Answer №2

Unfortunately, this approach did not yield the desired results for my project which utilizes vue 1.0.13. I found a workaround by creating a duplicate of the item without any data bindings like so:

this.items.push( JSON.parse( JSON.stringify( newItem ) ) );

Answer №3

LATEST UPDATE:

To create a clone without object references, consider using structuredClone:

  addItem: function(e) {
    e.preventDefault();
  
    this.items.push(structuredClone(this.newItem));
  }

ANOTHER OPTION:

An alternative approach is to utilize Object Spread:

  addItem: function(e) {
    e.preventDefault();
  
    this.items.push({...this.newItem});
  }

PREVIOUS METHOD:

If you prefer, you can stick with Vanilla JavaScript and Object.assign():

  addItem: function(e) {
    e.preventDefault();

    this.items.push(Object.assign({}, this.newItem));
  }

Answer №4

The answer at the top is inaccurate. Vue.util.extend is not related to jQuery's extend and only performs a shallow clone. Visit here for more information

Object.assign and the Spread operator also result in shallow copies. You can learn more about this here

To achieve a deep clone, consider using Ramda.js' implementation See implementation details here

If you do not require _curry, you can omit it.

For further insights on efficient ways to perform a deep clone of an object in JavaScript, check out this MVA: What is the most efficient way to deep clone an object in JavaScript?

Answer №5

structuredClone is a useful method, but there's a catch. It doesn't work with Proxies, which Vue 3 uses for reactivity. To clone an object using structuredClone in Vue 3, you first need to get the raw target and then clone it like this:

import { toRaw } from 'vue'
...
const copiedObject = structuredClone(toRaw(originalObject))

Answer №6

Implementing lodash library

import _ from 'lodash';


let clonedData = _.cloneDeep(this.formDataInitial);

let mergedData = _.merge(_.cloneDeep(this.formData), { filters: _.cloneDeep(this.formDataInitial.filters) });

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

Initiate the month transition event within the fomantic calendar

In my project, I have integrated the fomantic calendar and it is working properly. However, I am facing an issue when it comes to changing the month. Is there a specific event for month changes in the fomantic calendar? I am struggling to make it work. Tha ...

React's Conditional Rendering

Let's imagine having these initial conditions: this.state = {plans: [], phase: 'daybreak'} along with a dynamic JSON object fetched from an API containing various schedules that may change periodically, for example: plans = {"daybreak": " ...

What is the best way to link a generated PHP-AJAX link with a jQuery action?

Imagine a scenario like this: trollindex.htm: [...] <script> $(document).ready(function(){ $("* a.jquery").on("click",function(){ $.ajax({ type: "POST", url: "trollcommander.php", data: ({comman ...

Retrieve the part of a displayed element

Presently, I am developing a modal system using React. A button is located in the sidebar and the modal is represented as a div within the body. In the render function of the main component of my application, two components are being rendered: MyModal M ...

What distinguishes res.send from app.post?

I'm just starting to learn about express and HTTP. I've heard that the express library has app.get, app.post, and res.send methods. From what I gather, app.get is used for GET requests and app.post is used for POST requests. How does res.send fit ...

Can I update a label using ajax from the controller?

Hello everyone, I am facing a challenge in changing the text label coming from my Controller's JsonResult. There are two specific issues that I am encountering: 1) I am having difficulty displaying the text sent from my controller onto my view... ...

Save information in a session using html and javascript

I'm having trouble accessing a session variable in my javascript code. I attempted to retrieve it directly but ran into issues. As an alternative, I tried storing the value in a hidden HTML input element, but I am unsure of how to properly do that wit ...

Eslint can halt the Vue project build process if it encounters any errors

One day, while working on one of my Vue projects, I noticed that Eslint started causing build issues by flagging errors such as "Strings must use singlequote" or "Variable declared but never used". Surprisingly, the formatting errors were not being automat ...

Executing ESM-Enabled Script in Forever

Is it possible to execute a script using the option -r esm in Forever? When I try to run the configuration below, I encounter an error message that reads: Unexpected token import. Here is the configuration: { "uid": "app", "script": "index.js", "s ...

Use an inline style to apply a background image by utilizing a ternary operator

Is there a way for me to implement this code snippet only when the item.packageAtGradeImage.url is not null: <div v-bind:style="{ 'background-image': 'url(' + item.packageAtGradeImage.url + ')' }"></div> If so, h ...

Adjust the color of an SVG icon depending on its 'liked' status

In my React/TypeScript app, I have implemented an Upvote component that allows users to upvote a post or remove their upvote. The icon used for the upvote is sourced from the Grommet-Icons section of the react-icons package. When a user clicks on the icon ...

Tips on dividing a div into two separate pages when converting to PDF

I am working on an asp.net MVC project and I need to convert a HTML div into a PDF with two separate pages. Here is an example of my code: HTML Code <div class="row" id="mycanvas"> <p>This is the first part of my content.</p> <p ...

Guide on accessing values from an array of objects in JavaScript/Node.js

I am working with an array of objects that looks like this: const objArray = [{prop: "a", prop2 : "1"}, {prop: "b", prop2 : "2"}, {prop: "c"}, prop2 : "3"] My goal is to extract the property names of the objects in the array, rather than their values. D ...

Retrieve the link of a nearby element

My goal is to create a userscript that has the following functionalities: Add a checkbox next to each hyperlink When the checkbox is clicked, change the state of the corresponding hyperlink to "visited" by changing its color from blue to violet. However ...

Authentication through Proxy and requests from nodes

I am attempting to make a get request to a website via https using the request module. However, I am behind a proxy that requires authentication. Despite my attempts to add the authentication, the connection to the site fails. I have experimented with add ...

CSS and Javascript functioning correctly within internal server, but encountering issues when accessed externally

I am in the process of creating a website for a friend. The goal is to have a flashy animated style website that functions well on IOS and allows him to make changes easily. To achieve this, I am utilizing JQuery, my own javascript, and multiple css files. ...

Reconfigure the API to segment its components into individual variables

I'm currently working with an API that offers a wide range of available calls. In my VUE code, I am looking to modify it so that depending on which button is clicked, a different call is triggered. You can check out one example of this here: <> ...

Regardless of the circumstances, the Node.js PATCH request will always run

Apologies if the title is unclear, I struggled with how to phrase it. I encountered an issue with a PATCH request designed to update a value in my database: although it returns a "working" status (200), the actual update does not occur. I have a .route(&ap ...

What's the best way to retrieve the id or index of a card within a list?

Struggling to fetch the id's of documents retrieved from a MongoDB database and displayed on React and Material-Ui cards. Tried logging id in functions and APIs, but receiving 'undefined' or metadata from the delete function. Delete functi ...

What is the best way to apply a filter to an array of objects nested within another object in JavaScript?

I encountered an issue with one of the API responses, The response I received is as follows: [ {type: "StateCountry", state: "AL", countries: [{type: "County", countyName: "US"}, {type: "County", countyNa ...