Passing a copy of a data property to a function in Vue JS

vue pass data to component
vue props function
vue data
vue watch
vue pass data between components
vue pass data from one component to another
vue dynamic props
vue emit

I have a simple vue instance that I'm using to generate a Stripe token.

It looks like this:

var vm = new Vue({
        el: '#checkout-form',
        data: {
            stripe_publishable_key: '{{ config('services.stripe.publishable') }}',
            card: {
                number: null,
                cvc: null,
                exp: null,
            },
        },
        ready: function() {    
            Stripe.setPublishableKey(this.stripe_publishable_key);
        },
        methods: {
            getStripeToken: function() {
                Stripe.card.createToken(this.card, this.stripeResponseHandler);
            },
            stripeResponseHandler: function(status, response) {
                // Process response
            },
        },       
    });

Basically I pass the card object in my Vue instance (which is bound to some form inputs) to Stripe's card.createToken method. This should take the input and call the handler, passing in the response as it does so.

This all works fine except that card.createToken is modifying the card object and causing the card object on my Vue instance to change - it inserts its own properties and causes strange behaviour on the bound <inputs>.

Is there a way to pass the card vue property to Stripe as a copy which is unbound to the vue instance and thus won't change as a result?

Update

In essence this is happening because JavaScript passes objects as a copy-of-a-reference which means the original object can be modified by any function that receives it. The obvious solution is to clone the object by looping or some other means but I was wondering if there's a better way in Vue.

There are many ways to make a copy of this object, but only one from Vue itself:

var cardCopy = Vue.util.extend({}, this.card);

It is actually an equivalent to jQuery's extend with deep set to true.

How To Pass Data Between Components In Vue.js — Smashing , Let's analyze three of the most common ways to pass data in VueJS. pass the data from the parent ( ProfilePage.vue ), we pass it like a custom attribute. Copy. This means that we can change our data and have any child props The $emit method takes an optional second parameter for arguments. Then, to actually pass the data from the parent (ProfilePage.vue), we pass it like a custom attribute. // ProfilePage.vue <account-info username='matt' /> Now if we load our page, we can see that our AccountInfo component properly renders the value passed in by its parent.

Not that I know much Vie.js but is this.data is simply a JavaScipt object then you could clone it with this:

function cloneObject(obj) {
  var clone = {};
  Object.keys(obj).forEach(function(key) {
    clone[key] = obj[key];
  });
  return clone;
}

Or in ES3 land:

function cloneObject(obj) {
  var key, clone = {};
  for (key of obj) {
    if (obj.hasOwnProperty(key) {
      clone[key] = obj[key];
    }
  }
  return clone;
}

But this is a shallow clone so objects that are properties of the obj would not be cloned but their references would be the same (allowing mutation).

jQuery (if you have that) also provides a convenient way to do this:

var clone = $.extend({}, this.data);

And finally as @oleg-melashko pointed out Vue.js has a Vue.util.extend as well (though the documentation seems to lack any reference to this).

var clone = Vue.util.extend({}, this.data);

Components Basics — Vue.js, Instead, a component's data option must be a function, so that each instance can maintain an independent copy of the returned data object: data: function Once a prop is registered, you can pass data to it as a custom attribute, like this: How to use props to pass data to child components in Vue.js. August 6, 2019 5 min read 1436. In this post, we will look at how data can be passed from a parent component to child components in Vue.js.

There is coerce hook function for properties in Vue 1.0.12

It can be used for creation of object clone like that (ES6)

import _ from 'lodash';
export default{
    props: {
        myObjProp: {
            type: Object,
            coerce(val) {
                return _.clone(val);
            }
        }
    }
};

How to clone property value as simple object? - Get Help, When you pass data to vue element object props become reactive. object to vue element objects fields are replaced with properties with getter and setter functions due to (reactivity). How do I copy an object in JavaScript? The prop is used to pass in an initial value; the child component wants to use it as a local data property afterwards. In this case, it’s best to define a local data property that uses the prop as its initial value: props: ['initialCounter'], data: function { return { counter: this.initialCounter } }

You can also copy the card object like below

let cardCopy = JSON.parse(JSON.stringify(this.card));

Props — Vue.js, The prop is used to pass in an initial value; the child component wants to use it as a local data property afterwards. In this� Computed vs Watched Property. Vue does provide a more generic way to observe and react to data changes on a Vue instance: watch properties. When you have some data that needs to change based on some other data, it is tempting to overuse watch - especially if you are coming from an AngularJS

Vue.js passing and setting data via $emit - Get Help, with vuejs, and got into a situation where i want Component B to emit a method on Component A, with a passed object, and then set a local data property on� If you need to pass data to a component, you can use props to pass data down the tree (to child components), or events to pass data up the tree (to parent components). Props and data are both reactive. With Vue you don't need to think all that much about when the component will update itself and render new changes to the screen.

Tips & Best Practices, It is recommended to initialize all the data properties that needs to be reactive in Vue is passing down a parent method as a callback to the child using props . Vue.js: Why Components’ Data Properties Must Be Functions Published on May 2, 2017 by Bo Andersen I previously mentioned that with components, the data property must be a function and not an object as we are used to.

How to Pass a Function as a Prop in Vue, While you can pass a function as a prop, this is almost always a bad idea. Props and data flow down, and function calls flow up. Get exclusive VueJS content I'll say it again: Computed properties are the most important feature in Vue. Vue, why data must be a function the component will share this property. Go GraphQL HTML JavaScript Lab Network Next.js Node.js React Redis Services Svelte

Comments
  • seems like the most concise method, albeit this problem seems a little hacky to fix
  • @harryg it's undocumented built in function but it's accessible so we can use it ;)