ProNotion
ProNotion

Reputation: 3692

VueJs Data Passed From Root to Child Component via Prop Results in only an observable object

I have an app which calls a web service in the created() function and populates a property of the root data object. The property is passed via a prop to a child component and using the Chrome dev tools I can see that the prop data is available on the child component.

The problem I have is that I try to set data properties in the child component using values passed via the prop I end up with undefined property data. If I use the Chrome inspection tools and add a breakpoint I can see that the prop is an observable object in the form of {__ob__: Observer} and as such, I cannot directly access any of the data. My suspicion is that the child object sets it's data properties before the web service call has completed in the root.

How can I overcome this?

I've created a JsFiddle for this: https://jsfiddle.net/ProNotion/a8c6nqsg/

Vue.component("mycomponent", {
    template: '#my-component-template',
    props: ["customer_data"],
    data() {
        return {
            form_data: {
                customerEmail: this.customer_data.customerEmail1
            }
        }
    }
});

new Vue({
    el: "#app",
    data() {
        return {
            customer: {}
        };
    },
    methods: {
        init() {
            var self = this;
            axios.get("https://0bb1313e-b089-432e-b6bc-250f6162d7f0.mock.pstmn.io/GetCustomerData")
            .then(response => {
                self.customer = response.data;
            }).catch(response => {
                console.error(response);
            });
        }
    },
    created() {
        this.init();
    }
});

Here is my HTML markup:

<div id="app">
    <mycomponent :customer_data="customer" />
</div>

<script type="x-template" id="my-component-template">
    <div>
        <p>{{form_data.customerEmail1}}</p>
    </div>
</script>

Upvotes: 1

Views: 510

Answers (1)

ghlee
ghlee

Reputation: 106

Check response data type and format

console.log(typeof response.data) // string
{ "customerEmail1": "[email protected]", } // Remove `,`

You must parse to JSON type

axios.get(...).then(response => {
  self.customer = JSON.parse(response.data.replace(',', ''))
})

Set property to watch with `deep` option [Deep watching](https://v2.vuejs.org/v2/api/#vm-watch) will be detect nested value changes inside Objects ``` Vue.component("mycomponent", { template: '#my-component-template', props: ["customer_data"], data() { return { form_data: {} } }, watch: { customer_data: { handler (val) { this.form_data = val; }, deep: true } } }); ```

Demo: https://jsfiddle.net/ghlee/f4gewvqn

Upvotes: 1

Related Questions